/***
 * 富文本的通用，核心函数等非功能性的定义实现
 * 其他功能实现 放在 functions.js
 * @Author: kevin.huang 
 * ****/
var Kedit = function (jqObj, opts) {
    $B.extend(this, Kedit); //继承父类 
    var contents = jqObj.children().remove();
    var _this = this;
    this.doc = $(document);
    var  $w = window;
    this.opts = $.extend({}, defaultOpts, opts);
    this.jqObj = jqObj.addClass("k_box_size k_edit_main_wrap").css({
        width: this.opts.width,
        height: this.opts.height
    });
    var inputWrap = $("<div class='k_box_size k_edit_input_wrap' spellcheck='false' style='overflow: auto;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1'></div>");
    this.$input = $("<div spellcheck='false' contenteditable='true' style='overflow:visible;width:100%;min-height:100%;' class='k_box_size k_edit_input_filed'></div>").appendTo(inputWrap);
    this.$fixInput = this.$input;//区分固定，浮动输入框
    if(this.opts.mobile){
       this.$fixInput.addClass("k_dropdown_shadow");      
    }
    this.$inputWrap = inputWrap;
    this.tools = undefined;
    this.id = getUUID();
    this.undoStack = new Stack(this.opts.undoSize);
    this.redoStack = new Stack(this.opts.undoSize);
    inputWrap.appendTo(this.jqObj);
    this.range = undefined;
    this.painTargets = []; //选区内所有需要修饰的元素   
    this.tables = [];
    this.windowArray = [];
    this.clickActivedObject = undefined; //当前点击激活的表格,图像
    this._initInputEvents(this.$input);
    if (this.opts.createToolbars) {
        this.tools = this.opts.createToolbars(this);
    } else {
        this.tools = new Toolbars(this);
    }
    if (this.tools && this.tools.height) {
        var height = this.tools.height();
        inputWrap.css("border-top", (height + 4) + "px solid #fff");
        if(height === 0){ //修复在隐藏tab里面创建 高度为0的bug
            var fixHeightIvt = setInterval(function(){
                if(_this.tools){
                    height = _this.tools.height();
                    if(height > 0){
                        inputWrap.css("border-top", (height + 4) + "px solid #fff");
                        clearInterval(fixHeightIvt);
                    }       
                }else{
                    clearInterval(fixHeightIvt);
                }                        
            },300);
        }
    }
    setTimeout(function () {
        if (contents.length > 0) {
            _this.setContent(contents);
        }
        _this.insertPElement();
    }, 1);
    window["curEditor"] = this;
    $(document).on("mousedown."+this.id ,function(e){//处理 margin-left区域鼠标点击事件
        //console.log("document mouse down >>>>");
        var pageX = e.pageX;
        var pageY = e.pageY;
        var ofs = _this.jqObj.offset();
        var w = _this.jqObj.width();
        var h = _this.jqObj.height();
        if(ofs.left < pageX  && pageX < ( ofs.left + w)   && pageY < (ofs.top + h) && pageY > ofs.top){
            stopDefaultctxMenu();
            //console.log("document mouse down >>>>>>>");
        }
    });
    if(this.opts.mobile){
        for(var i = 0 , len = eConfig.mobiles.length ; i < len ;++i){
            if(eConfig.mobiles[i].default){
                this.mobile({phonesize : eConfig.mobiles[i].size}); 
                break;
            }
        }
    }
    this.FLOW_CACHE = {};
    $w["_b_u_i_editor__"]=1;
    this._cache_clearner = setInterval(function(){
        var keys = Object.keys(_this.FLOW_CACHE);
        for(var i = 0 ,len = keys.length ; i < len ;++i){
           if(inputWrap.find("#"+keys[i]).length === 0 ){
               delete _this.FLOW_CACHE[keys[i]];
           }
        }
    },300000);
};
Kedit.prototype = {
    constructor: Kedit, 
    /**内容发生变化
     * skip：是否跳过 _setCurrentHtml() 调用
     * ***/
    _onChange: function (skip) {
        if (this.opts.onChange) {
            var _this = this;
            if(!skip){
                this._setCurrentHtml();
            }           
            clearTimeout(this.onChangeTimer);
            this.onChangeTimer = setTimeout(function () {
                var content = _this.getContent();
                _this.opts.onChange(content);
            },500);
        }
    },
    /**
     * 先提前需要保持的html
     * ***/
    _setCurrentHtml:function(){
        this.currentHTML =  this.$fixInput.children().clone();
        this.currentFloatHTML = this.$inputWrap.children(".k_edit_float_panel").clone();
    },
    _clearCurrentHtml:function(){
        this.currentHTML =  undefined;
        this.currentFloatHTML = undefined;
    },
    /**
     * 禁用工具栏按钮
     * ***/
    disabledFunc: function (enabledList) {
        this.tools.$wrap.children("div").each(function () {
            var $t = $(this);
            var key = $t.attr("key");
            if (!enabledList[key] && key !== "redo" && key !== "undo") {
                $t.addClass("k_edit_tools_disabled");
            }
        });
    },
    /***
     * 启用工具栏按钮
     * **/
    enabledFunc: function () {
        this.tools.$wrap.children("div").each(function () {
            var $t = $(this);
            var key = $t.attr("key");
            if (key !== "redo" && key !== "undo") {
                $t.removeClass("k_edit_tools_disabled");
            }
        });
    },
    /**
    * 创建浮动窗口
    * **/
    _createFloatWindow: function (width, height) {
        if (!this.floatTools) {
            this.floatTools = new FloatTools(this);
        }
        if (!this.floatPropPanel) {
            this.floatPropPanel = new FloatPropPanel(this);
        }
        var left,top;
        if(this.opts.mobile){//移动设备模拟
            var inputWidth = this.$fixInput.width();
            var inputHeight = this.$fixInput.height();
            width = inputWidth *  0.6 ;
            height = inputHeight *  0.2 ;
            left = parseInt(this.$fixInput.css("margin-left").replace("px","")) + (inputWidth -  width) / 2 ;
            top = 60 + this.$inputWrap.scrollTop();
        }else{
            left = (this.$fixInput.width() - 400) / 2 + this.$inputWrap.scrollLeft();
            top = 100 + this.$inputWrap.scrollTop();
        }
        var uuid = getUUID();
        var wrap = $("<div id='"+uuid+"' class='k_box_shadow k_edit_float_panel' style='-moz-box-shadow: 0px 0px 3px 3px #D8D8D8;-webkit-box-shadow: 0px 0px 3px 3px #D8D8D8;box-shadow: 0px 0px 3px 3px #D8D8D8;z-index:20000000;background:none;width:" + width + "px;height:" + height + "px;position:absolute;top:" + top + "px;left:" + left + "px;'></div>");
        $("<div class='k_float_opacity_' style='width:100%;height:100%;position:absolute;z-index:20000000;background:#fff;top:0;left:0;-moz-opacity: 0.5;-khtml-opacity: 0.5;opacity: 0.5;'></div>").appendTo(wrap);
        wrap.appendTo(this.$inputWrap);
        this._bindFlowWrapEvnets(wrap);
        setTimeout(function () {
            wrap.trigger("mouseup");
        }, 10);
        return wrap;
    },
    /***绑定浮动框事件**/
    _bindFlowWrapEvnets: function (wrap) {
        var _this = this;
        wrap.mouseup(function () {
            var box = $(this);
            var matrix = box.css("transform");
            var angle = $B.getMatrixAngle(matrix);
            if (angle === 0) {//角度为0才可以resize
                _this._createResizeBox(box);
                _this["resizeBox"].bind(box);
            }
            _this.floatTools.show(box);
        });
    },
    /***
     * 绑定浮动框 顶部拖动工具条事件
     * **/
    _bindFloatPanelEvents: function (wrap) {
        if (!this.floatTools) {
            this.floatTools = new FloatTools(this);
        }
        if (!this.floatPropPanel) {
            this.floatPropPanel = new FloatPropPanel(this);
        }
        this._bindFlowWrapEvnets(wrap);
        var wrapInner = wrap.children("div").eq(1);
        var isImg = wrapInner.children("img").length > 0;
        if (isImg) {//图片
            wrapInner.addClass("k_editor_float_img_wrap k_box_size");
            this._bindFlowImgEvents(wrapInner);
        } else {//
            wrapInner.addClass("k_editor_float_input k_box_size").attr({
                "spellcheck": "false",
                "contenteditable": "true"
            });
            this._initInputEvents(wrapInner);
            return wrapInner;
        }
    },
    /**
     * 创建resizeBox
     * **/
    _createResizeBox: function (box) {
        if (!this["resizeBox"]) {
            var _this = this;
            var resize = new $B.Resize({
                target: box,
                zoomScale: false,
                dragStart: function (args) {
                    _this.resizing = true;
                    if (_this["tipWindow"]) {
                        _this["tipWindow"].hide();
                    }
                },
                dragEnd: function (args) {
                    _this.resizing = false;
                    if (_this.floatTools && resize.target.hasClass("k_edit_float_panel")) {
                        if (_this.floatTools.wrap.css("display") !== "none") {
                            _this.floatTools.show(resize.target);
                        }
                    } else {
                        var box = _this["resizeBox"];
                        if (box.target[0].tagName === "VIDEO") {//如果是视频拖动
                            var width = box.line1.width();
                            var height = box.line2.height();
                            var player = box.target.parent().parent().data("player");
                            player.width(width);
                            player.height(height);
                        }
                    }
                    resize.bind(resize.target);
                },
                onDrag: function () {
                    var box = _this["resizeBox"];
                    if (box.target[0].tagName === "VIDEO") {//如果是视频拖动
                        return false;//阻止更新
                    }
                    return true;
                }
            });
            this["resizeBox"] = resize;
            //this["resizeBox"].disable("left");
        } else {
            this["resizeBox"].bind(box);
        }
    },
    /***更新元素el的id***/
    _updateId: function (el) {
        if (el[0].tagName !== "BR") {
            var _this = this;
            var id = getUUID();
            el.attr("id", id);
            el.children().each(function () {
                _this._updateId($(this));
            });
        }
    },
    /***
     * 从数组中
     * 移除无用的table/image等组件
     * ***/
    removeUselessComponent: function () {
        var _this = this;
        clearTimeout(this["rmUselesscomTimer"]);
        this["rmUselesscomTimer"] = setTimeout(function () {
            var newTablesArray = [];
            for (var i = 0, len = _this.tables.length; i < len; ++i) {
                var comp = _this.tables[i];
                var jqObj = comp.jqObj;
                var p = jqObj.parent();
                if (p.length !== 0) {
                    newTablesArray.push(comp);
                } else {
                    comp.destroy();
                }
            }
            _this.tables = newTablesArray;
        }, 1000);
    },
    /**
     * 打开提示窗口
     * args = {
     *      top:,
     *      left:
     * }
     * createFn创建tip内容的函数
     * **/
    openTIPWindow: function (pos, createFn) {
        var _this = this;
        if (!this["tipWindow"]) {
            this["tipWindow"] = $("<div style='width:auto;' class='k_edit_window k_box_size k_box_shadow'><div style='border:0;position:static;padding:0 12px;' class='k_edit_window_body k_box_size'></div></div>");
            this["tipWindow"].appendTo(_getBody());
            this["tipWindow"].on("mousedown", function () {
                stopDefaultctxMenu();
            });
        }
        var body = this["tipWindow"].children();
        body.children().detach();
        createFn(body, pos);
        body.children().show();
        this["tipWindow"].css(pos).fadeTo(300, 1);
    },
    /**关闭tip窗口**/
    closeTIPWindow: function () {
        var _this = this;
        if (this["tipWindow"] && this["tipWindow"].css("display") === "block") {
            this["tipWindow"].fadeTo(100, 0.1, function () {
                _this["tipWindow"].hide();
            });
        }
    },
    /**
     * 打开请求远程页面窗口
     * **/
    openPageWindow: function (args, params, onDragStopFn) {
        this.openWindow(args, params, onDragStopFn, 'pageWindow');
        this.closeRemoveDom = true;
    },
    /**打开窗口
     * 可以在打开窗口时候注册 this.onWindowClosed 关闭回调，
     * this.onWindowClosed是临时性的，一旦调用后 即被设置为undefined
     * args ={
     *    title: ,
     *    width: ,
     *    height: ,
     *    contentFn:内容创建fn  
     * }
     * **/
    openWindow: function (args, params, onDragStopFn, windowName) {
        this.closeRemoveDom = false;
        var _this = this;
        if (typeof onDragStopFn === "function") {
            _this["onWidDragStopFn"] = onDragStopFn;
        } else {
            _this["onWidDragStopFn"] = undefined;
        }
        var winName = "window";
        if (typeof windowName !== "undefined") {
            winName = windowName;
        }
        this.windowName = winName;
        if (!this[winName]) {
            this[winName] = $("<div style='z-index:2147483647;' class='k_edit_window k_box_size k_box_shadow'><div tabindex='0' class='k_edit_window_header k_box_size'><span class='k_edit_window_label'></span><a tabindex='0'><i class='fa fa-cancel-2' tabindex='0'></i></a></div><div  class='k_edit_window_body k_box_size'><iframe class='current_window_ifr' frameborder='0' width='100%' height='100%' scrolling='no'></iframe></div></div>");
            this[winName].appendTo(_getBody());
            this[winName + "_iframe"] = this[winName].children(".k_edit_window_body").children("iframe");
            var ifr = this[winName + "_iframe"][0];
            var doc = ifr.contentWindow.document || ifr.contentDocument;           
            var linkArr = getCssloadString(this.flowScriptSrcs);            
            doc.open().write(linkArr);
            doc.close();
            this[winName + "_doc"] = doc;
            this[winName + "_body"] = $(doc.body).css({
                "margin": 0,
                "padding": 4
            });
            var header = this[winName].children(".k_edit_window_header");
            header.children("a").click(function () {
                _this.closeWindow();
                _getBody().css("cursor", "default");               
                return false;
            });
            this[winName].draggable({
                onDragReady: function () {
                    var picker = _this[winName].data("colorPicker");
                    if (picker) {
                        picker.hide();
                    }
                    return true;
                },
                onStopDrag: function (args) {
                    if (_this["onWidDragStopFn"]) {
                        _this["onWidDragStopFn"](args);
                    }
                },
                notClearRange: true,
            });
            this[winName + "_body"].click(function () {
                var picker = _this[winName].data("colorPicker");
                if (picker) {
                    picker.hide();
                }
            });
            var onFocus = function () {
                _this.rebuildUserRange();
                return false;
            };
            var bindFocus = function (ele) {
                ele.on("focus", onFocus);
                ele.children().each(function () {
                    bindFocus($(this));
                });
            };
            bindFocus(header);
            this.windowArray.push(this[winName]);//用于销毁
        }
        if (!this.mask) {
            this.mask = $("<div style='z-index:5' class='k_model_mask'></div>").appendTo(this.jqObj);
        }
        this[winName].children(".k_edit_window_header").find(".k_edit_window_label").html(args.title);
        this.closeTIPWindow();
        this._closeCxtMenu();
        var ofs = this.jqObj.offset();
        var top = ofs.top + (this.jqObj.outerHeight() / 2) - args.height / 2;
        var left = ofs.left + (this.jqObj.outerWidth() / 2) - args.width / 2;
        if(top < 0){
            top = 1;
        }       
        this[winName].css({
            width: args.width,
            height: args.height,
            top: top,
            left: left
        }).fadeTo(200, 1, function () {
            _this.mask.show();
        });
        if(winName !== "flowDesignWindow"){
            this[winName + "_body"].children().detach();
        }       
        args.contentFn(this[winName + "_body"], params, this[winName + "_doc"]);
    },
    /**关闭打开的
     * 关闭窗口
     * **/
    closeWindow: function () {
        if (window["_codeCssObject_"]) {
            window["_codeCssObject_"].removeTargets();
        }
        var wName = this.windowName;
        if (this[wName]) {
            var _this = this;
            var colorPicker = _this[wName].data("colorPicker");
            if (colorPicker) {
                colorPicker.opts.change = undefined;
            }
            this[wName].fadeTo(300, 0.1, function () {
                var w = $(this).hide();
                if (_this.closeRemoveDom || w.data("rmDom") ) {
                    w.remove();
                    _this[wName] = undefined;
                    _this[wName + "_iframe"] = undefined;
                    _this[wName + "_body"] = undefined;
                    _this[wName + "_doc"] = undefined;
                }
                _this.mask.hide();
            });
            _getBody().css("cursor", "default");
            if (this.closedSections && this.closedSections.length > 0) {
                for (var i = 0, len = this.closedSections.length; i < len; ++i) {
                    this.closedSections[i].removeClass("k_editor_closed_section");
                }
            }
            this.closedSections = [];
            this.removeSectionResizeBar();
            setTimeout(function(){
                if(_this.onWindowClosed){
                    _this.onWindowClosed();
                    _this.onWindowClosed = undefined;
                }
            },100);            
        }
        this.flowUpdateImg = undefined;//清理打开流程编辑设置的更新对象
    },
    /**获取光标所在的段落div**/
    getAnchorSectionEl: function () {
        var anchor = this.getAnchorJqNode();
        while (anchor.length > 0) {
            if (anchor[0].tagName === "DIV") {
                break;
            }
            anchor = anchor.parent();
        }
        return anchor;
    },
    /**
    * 显示右键菜单
    * ofs:位置
    * hideItems = [] 需要隐藏的项目
    * **/
    showMouseMenu: function (ofs, hideItems) {
        var diff = _getBody().height() - ofs.top;
        if (diff < 135) {
            ofs.top = ofs.top - 155;
        }
        diff = _getBody().width() - ofs.left;
        if (diff < 110) {
            ofs.left = ofs.left - 110;
        }
        var _this = this;
        var i, len;
        if (!this["mousemenu"]) {
            this["mousemenu"] = $('<div class="k_edit_input_ctxmenu k_box_shadow" style="width:auto;position:absolute;z-index:99999999;display:none;background:#ffffff;border:1px solid #E0E0E0;"></div>').appendTo(_getBody());
            var _focusFn = function () {
                _this.rebuildUserRange();
                return false;
            };
            var _clickFn = function () {
                var $t = $(this);
                var _handler = $t.data("handler");
                var _params = $t.data("params");
                setTimeout(function () {
                    _this.hideMouseMenu();
                }, 100);
                _this.execute(_handler, _params);
            };
            for (i = 0, len = config.mouseMenu.length; i < len; ++i) {
                var it = config.mouseMenu[i];
                var icon = it.icon,
                    title = it.title,
                    handler = it.handler,
                    params = it.params;
                var $it = $("<div tabindex='0' class='_" + handler + "'><i style='padding-right:4px;' class='fa " + icon + "'></i><span>" + title + "</span></div>").appendTo(this["mousemenu"])
                    .focus(_focusFn).click(_clickFn).data("handler", handler).data("params", params);
                $it.children().focus(_focusFn);
                if (it.tip) {
                    $it.attr("title", it.tip);
                }
            }
            this["mousemenu"].mousedown(function () {
                stopDefaultctxMenu();
            });
        }
        this["mousemenu"].children().show();        
        if (hideItems && hideItems instanceof Array) {
            for (i = 0, len = hideItems.length; i < len; ++i) {
                this["mousemenu"].children("._" + hideItems[i]).hide();
            }
        }
        for(i = 0, len = this.defaultHideMouseIts.length; i < len; ++i){
            this["mousemenu"].children("._" + this.defaultHideMouseIts[i]).hide();
        }

        var $p = this.getAnchorSectionEl();
        var closed_count = $p.attr("closed_count");
        var $n = this["mousemenu"].find("._closedNext");
        if (closed_count) {
            $n.children("span").text(eConfig.label.cancelNext);
        } else {
            $n.children("span").text(eConfig.label.closedNext);
        }
        var style = this._style2CssObject($p);
        if (style.width && style.width !== "auto") {
            this["mousemenu"].find("._resetSectionWidth").show();
        } else {
            this["mousemenu"].find("._resetSectionWidth").hide();
        }
        this["mousemenu"].css(ofs).show();
    },
    /***隐藏鼠标菜单***/
    hideMouseMenu: function () {
        if (this["mousemenu"]) {
            this["mousemenu"].hide();
        }
    },
    /***移除段落宽度设置拖动条***/
    removeSectionResizeBar: function () {
        if (this.sectionResizeBar) {
            this.sectionResizeBar.remove();
            this.sectionResizeBar = undefined;
        }
        if (this.sectionResizeBar2) {
            this.sectionResizeBar2.remove();
            this.sectionResizeBar2 = undefined;
        }
        if (this.resizePelement) {
            for (var i = 0, len = this.resizePelement.length; i < len; ++i) {
                this.resizePelement[i].removeClass("k_editor_closed_section");
            }
            this.resizePelement = undefined;
        }
    },        
    /**关闭所有显示的窗口**/
    closeAllWindow: function () {
        this.closeTIPWindow();
        this.hideMouseMenu();
        if (this["resizeBox"]) {
            this["resizeBox"].unbind();
        }
    },
    /***初始化输入框事件
     * ***/
    _initInputEvents: function ($input) {
        var _this = this;
        var reSaveRange = false;
        var isClosed = false;
        var clearColosedTimer;
        var clearRangeTimer;           
        var inputMouseUpEnvent = function(e){
            _this.go2docListner = false;
            var clearClickObject = true;
            var parent = e.target;
            var nodeName;
            while (parent) {
                nodeName = parent.nodeName;
                if (nodeName === "DIV") {
                    break;
                }
                if (nodeName === "TD") {
                    clearClickObject = false;
                    break;
                }
                parent = parent.parentNode;
            }
            if (clearClickObject) {
                _this.clickActivedObject = undefined;
            }
            if (_this.clickActivedDomObject) { //当前点击的是一个dom-jq对象
                _this.clickActivedDomObject.removeClass("k_edit_actived_object");
                _this.clickActivedDomObject = undefined;
            }
            //是否是格式刷操作
            if (_this.brushCss) {
                _this.brush2Target();
            }
           
            setTimeout(function () {              
                _this.saveUserRange();                
                if (reSaveRange) {
                    //_this.saveUserRange();
                    if (e.which === 3 && e.target.nodeName !== "A") {
                        var hideItems = ['editLink', 'unlink'];
                        parent = $(parent);
                        var showClosed = false;
                        if (nodeName === "DIV") {
                            showClosed = _this.getDomRange().collapsed;
                            if (showClosed) {
                                var elLen = parent.width();
                                var chLen = 0;
                                parent.children().each(function () {
                                    chLen = chLen + $(this).width();
                                });
                                if (chLen < elLen) {
                                    showClosed = true;
                                }
                            }
                        }
                        showClosed = _this.getAnchorSectionEl().next("._section_div_").length > 0;
                        if (!showClosed) {
                            hideItems.push("closedNext");
                        }
                        //浮动文本框 需要隐藏的项目
                        if (_this.$input.hasClass("k_editor_float_input")) {
                            hideItems.push('showInsertImageWindow');
                            hideItems.push('setSectionMove');
                        }
                        _this.showMouseMenu({
                            top: e.pageY,
                            left: e.pageX
                        }, hideItems);
                    }
                }
                reSaveRange = false;
                //工具栏联动
                if (_this.tools && typeof _this.tools.clickSubscribe === "function") {
                    var rangeCss = _this._getRangeCss(false,false,true);
                    _this.tools.clickSubscribe(_this, rangeCss);
                }
                var eventNode = e.target;
                var isTdEle = eventNode.nodeName === "TD";
                while (eventNode.nodeName !== "DIV" && !isTdEle) {
                    eventNode = eventNode.parentNode;
                    if (!eventNode) {
                        break;
                    }
                    isTdEle = eventNode.nodeName === "TD";
                    if (eventNode.nodeName === "LI") {
                        break;
                    }
                }
                if (!isTdEle) { //避免取消当前点击的单元格
                    for (var i = 0, len = _this.tables.length; i < len; i++) {
                        if (typeof _this.tables[i].clickSubscribe === "function") {
                            _this.tables[i].clickSubscribe(_this);
                        }
                    }
                }
            }, 50);
        };
        if($input.hasClass("k_edit_input_filed")){
            //注册dom mouseup 解决划选时候，鼠标在input区域外无法触发inputMouseUpEnvent的场景
            var $doc = $(window.document);
            var event = 'mouseup.'+this.id;
            $doc.off(event);
            $doc.on(event , function(e){
                if(_this.go2docListner){
                    //console.log("go2docListner mouseup.paintBrushlistener");
                    _this.go2docListner = false;
                    inputMouseUpEnvent(_this.mouseDownArgs);
                } 
                _this.mouseDownArgs = undefined;              
            });
        }
        window["_b_u_i___"]= true;
        //应该加入双击全选功能
        $input.on("mousedown", function (e) {  
            if( _this.imgMask){
                _this.imgMask.remove();
                _this.imgMask = undefined;
            }
           // console.log("input mouse down event!"); 
           if(e.which === 3){
                stopDefaultctxMenu(); 
           }                         
            if (_this.movingAcn && !_this.movingScroll) {
                _this.movingAcn.hide();
            }
            _this.removeSectionResizeBar();
            _this.closeAllWindow();
            var $i = $(this);
            _this.$input = $i;
            var isFloatInput = $i.hasClass("k_editor_float_input");
            if (isFloatInput) {//浮动文本输入
                _this.disabledFunc(eConfig.floatEidtor);
            } else {
                _this.enabledFunc();//启用按钮
                if (_this.floatTools) {
                    _this.floatTools.hide();
                }
            }            
            reSaveRange = true;
            _this._clearRangeRecord();
            _this.go2docListner = true;
            _this.mouseDownArgs = e;

        }).on("keyup", function (e) {
            if (_this.isPasting) {
                return false;
            }
            //回车 需要处理空br、li内回车、td内回车的问题！
            var isDeleted = e.keyCode === 8 || e.keyCode === 46;
            //console.log(" e.keyCode  = "+e.keyCode);
            var domRange = _this._getDomRangeOnly();
            var commonAncestorContainer = domRange.commonAncestorContainer;
            if(e.keyCode === 39){
                if (commonAncestorContainer.nodeType === 1 && commonAncestorContainer.nodeName === "SPAN") {
                    var  $c = $(commonAncestorContainer);
                    if($c.children("img").length > 0){
                        if($c.next("span").length === 0 ){
                           var newspan = _this._getSpan().insertAfter($c);
                           _this.moveToEnd(newspan);
                        } 
                    }
                }
            }
            if (isDeleted) {
                if (commonAncestorContainer.nodeType === 1 && commonAncestorContainer.nodeName === "DIV") {
                    var s1 = $(commonAncestorContainer);
                    var preS1 = s1.prev();
                    if (preS1.length > 0) {
                        s1.remove();
                        _this.moveToEnd(preS1);
                    }
                }
                //处理删除后的处理，检查table是否还存在,处理顺序列表问题
                _this.onDeleteKeyup(e.keyCode);
            }
            var isCode = false;
            var node = _this.getAnchorJqNode();
            var isLi = false,
                liTag,
                isTd = false,
                tagName,
                parentNode;
            if (node[0].tagName === "PRE") {
                isCode = true;
            }
            //检测是否是列表li里的回车
            if (node[0].tagName !== "DIV") {
                parentNode = node.parent(); //parentNode递归到段落div 
            } else {
                parentNode = node;
            }
            var $pre, $pElement;
            while (parentNode.length > 0) {
                tagName = parentNode[0].tagName;
                if (tagName === "DIV") {
                    break;
                }
                if (tagName === "LI") {
                    isLi = true;
                    liTag = parentNode;
                }
                if (tagName === "TD") {
                    isTd = true;
                }
                if (tagName === "P") {
                    $pElement = parentNode;
                }
                if (tagName === "PRE") {
                    $pre = parentNode;
                    isCode = true;
                }
                parentNode = parentNode.parent();
            }
            if (isCode) {
                if ($pre) {//pre元素内回车
                    $pre.remove();
                    var newPel = _this.createPElement();
                    newPel.insertAfter(parentNode);
                    _this.moveToEnd(newPel);
                }
                return false;
            }
            if (e.keyCode === 13) {                
                var updateTag = parentNode;
                if (isTd) {
                    updateTag = $pElement;
                } else if (isLi) {
                    updateTag = liTag;
                } else { }
                /***继承上一行高***/
                var prevEl = updateTag.prev();
                var lineHeight = prevEl.css("line-height");
                var paddingLeft = prevEl.css("padding-left");
                //var maxFs = _this._getParagraphMaxFontSize(updateTag);
                updateTag.css({ "line-height": lineHeight, "padding-left": paddingLeft });
                //段落回车自动序号支持
                var isPel = prevEl[0].tagName === "DIV" || prevEl[0].tagName === "P";
                if (isPel) {
                    _this._autoSeq(updateTag, prevEl);
                    _this.moveToEnd(updateTag);//回车后确保输入焦点不在序列span
                }
                var currentId = updateTag.attr("id");
                _this._updateId(updateTag);
                _this.clearUserRange();
                if (updateTag.text() === "\u200B") {
                    _this.moveToEnd(updateTag);
                }
                if (!isLi && !isTd) {
                    _this["undoRedoRec"].replaceSectionId.push(parentNode.attr("id"));
                }
                _this._putUndo();
                //段落绑定事件
                updateTag.bind("mouseenter", { "_this": _this }, _this.bindSectionElEvent);
                //修正id
                while(prevEl.length > 0){
                    if(prevEl.attr("id") === currentId){
                        _this._updateId(prevEl);
                        prevEl = prevEl.prev();
                    }else{
                        break;
                    }
                }
            } else {
                //预防在span标签中存在文字和子标签                   
                var range = _this.getDomRange(false);
                if (range) {
                    var pNode, newSpan;
                    var ancContainer = range.commonAncestorContainer;
                    if (ancContainer.nodeType === 3) {
                        var val = ancContainer.nodeValue;
                        pNode = ancContainer.parentNode;
                        if (val !== "" && pNode.tagName !== "TD") {
                            if (ancContainer.nextSibling) {
                                pNode.removeChild(ancContainer);
                                newSpan = _this._getSpan().html(val).insertBefore($(pNode));
                                _this.moveToEnd(newSpan);
                            } else if (ancContainer.previousSibling) {
                                pNode.removeChild(ancContainer);
                                newSpan = _this._getSpan().html(val).insertAfter($(pNode));
                                _this.moveToEnd(newSpan);
                            }
                        }
                    }
                    if (e.keyCode === 9) { //tab键
                        range = _this.getDomRange(false);
                        ancContainer = range.commonAncestorContainer;
                        var startOffset = range.startOffset,
                            endOffset = range.endOffset;
                        if (startOffset === endOffset) {
                            var nodeValue = ancContainer.nodeValue;
                            pNode = $(ancContainer.parentNode);
                            var arr = [], v;
                            var newStart = startOffset;
                            if (nodeValue === "\u200b") {
                                arr.push("\u200b");
                                arr.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                                newStart = newStart + 4;
                            } else {
                                for (var i = 0, len = nodeValue.length; i < len; ++i) {
                                    if (startOffset === 0 && i === 0) {
                                        arr.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                                        newStart = newStart + 4;
                                    }
                                    v = nodeValue[i];
                                    if (v === "\u200b") {
                                        v = "\u200b";
                                    }
                                    arr.push(v);
                                    if (i === (startOffset - 1)) {
                                        arr.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                                        newStart = newStart + 4;
                                    }
                                }
                            }
                            nodeValue = arr.join("");
                            pNode.html(nodeValue);
                            var el = pNode[0].firstChild;
                            _this.setCrossRange(el, el, newStart, newStart);
                        }
                    }
                }
                clearTimeout(_this["saveUserRangeTimer"]);
                _this["saveUserRangeTimer"] = setTimeout(function () {
                    _this.saveUserRange();
                    if (e.ctrlKey && e.keyCode === 65) { //全选场景，需要重新设置划选的标签
                        _this.setPaintTarget();                     
                    }
                }, 500);
            }
        });
        $input.parent().on("scroll", function () {
            if (_this.movingAcn && !_this.movingScroll) {
                _this.movingAcn.hide();
            }
            if (_this.resizing) {
                return true;
            }
            if (!isClosed) {
                _this.closeAllWindow();
                isClosed = true;
                for (var j = 0, jlen = _this.tables.length; j < jlen; ++j) {
                    _this.tables[j].hideMenu();
                }
            }
            if(_this.floatTools){
                _this.floatTools.onScroll();
            }
            clearTimeout(clearColosedTimer);
            clearColosedTimer = setTimeout(function () {
                isClosed = false;
            }, 1000);
        });       
        // 跨行删除的撤销重做问题
        // 回车换行撤销 重做有问题
        $input.on("keydown", function (e) {
            _this.closeAllWindow();
            var code = e.keyCode;
            var txt;            
            if (e.keyCode === 13) { //回车
                _this._onChange();
                _this.saveUserRange();
                _this._makeUndoDataByFocus();
            } else if (code === 8 || code === 46) { //删除操作
                if (!_this.range) {
                    _this.saveUserRange();
                }
                _this._onChange();
                var range = _this.range;
                _this["isSelectedContent"] = !range.collapsed;
                var anchorNode = range.commonAncestorContainer;
                var node;
                if (anchorNode["nodeType"] === 3) {
                    node = $(anchorNode.parentNode);
                } else {
                    node = $(anchorNode);
                }
                //最后一个段落div不能被删除
                if (!node.hasClass("k_edit_input_filed") && node.hasClass("_section_div_")) {
                    txt = node.text();
                    if (node.siblings().length === 0) {
                        if (txt === "" || txt === "\u200B") {
                            return false;
                        }
                    }
                }
                while (node.length > 0) {
                    if (node.hasClass("_section_div_") || node.hasClass("k_edit_input_wrap") || node.hasClass("k_editor_float_input")) {
                        break;
                    }
                    node = node.parent();
                }
                txt = node.text();
                _this.isEmptySection = txt === "" || txt === "\u200B";
                if (_this.isEmptySection && node.siblings().length === 0) { // 
                    return false;
                }
                //创建undo栈的记录数据并入栈
                _this._makeUndoDataByFocus();
                _this._putUndoDelayed();
            }
        });

        /***避免选择时候，鼠标移出编辑区域的情况***/
        $input.on("mouseup", inputMouseUpEnvent).on("mouseleave", function () { //应该采用mouseout，避免
            setTimeout(function () {
                if (reSaveRange) {
                    _this.saveUserRange();
                }
                reSaveRange = false;
            }, 200);
        });
        $input.on("paste", { _this: this }, _this.onPaste);
    }, /**段落回车自动序号支持
    * 支持序列格式 : 1. 2. | 1、2、| 一. 二. | 一、 二 、
    * ***/
    _autoSeq: function (updateTag, prevEl) {
        var _this = this;
        var seqRes = _this._getSectionSeqDatas(prevEl);
        if (seqRes.isSeq) {
            //分析提取回车行序列
            var seqEl = seqRes.seqEl;
            var seqSpanEl = seqEl;
            var nodeText = seqRes.nodeText;
            var seqNum = seqRes.seqNum;// 
            var seqNumTxt = seqRes.seqNumTxt;
            seqEl.html(nodeText.replace(seqNumTxt, ""));
            var cssStyle = _this._getCopyStyle(seqEl);
            var newSpan = _this._getSpan().css(cssStyle);
            //将序列前面的空元素内容合并到newSpan中，并删除空元素
            for (var i = 0, len = seqRes.emptyEl.length; i < len; ++i) {
                var rmEl = seqRes.emptyEl[i];
                var html = rmEl.html();
                seqNumTxt = html + seqNumTxt;
                rmEl.remove();
            }
            seqNumTxt = "\u200B" + seqNumTxt;
            newSpan.html(seqNumTxt).insertBefore(seqEl);
            //生成新行序列    
            var nextSeq, nextSeqText, nextChseq, chSeqIndex;
            if (seqRes.isChSeq) {
                nextChseq = getChNextSeq(seqNum);
                nextSeq = nextChseq.seq;
                nextSeqText = seqNumTxt.replace(seqNum, nextSeq);
                chSeqIndex = nextChseq.index;
            } else {
                nextSeq = seqNum + 1;
                nextSeqText = seqNumTxt.replace(/\d+/g, nextSeq);
            }
            var nextpan = _this._getSpan().css(cssStyle);
            nextpan.html(nextSeqText);
            updateTag.prepend(nextpan);
            var acnSpan = nextpan.next();
            if (acnSpan.length > 0) {
                this.moveToStart(acnSpan);
            }
            var nextPelement = updateTag.next("._section_div_");
            var count = 0;
            while (nextPelement.length > 0) {//更新后面的序列排序                   
                seqRes = _this._getSectionSeqDatas(nextPelement);
                if (seqRes.isSeq) {
                    seqEl = seqRes.seqEl;
                    if (_this._isSameSeq(seqNumTxt, seqRes.seqNumTxt, seqSpanEl, seqEl)) {
                        count = 0;
                        if (seqRes.isChSeq) {
                            chSeqIndex++;
                            nextSeq = chSeqArray[chSeqIndex];
                            nextSeqText = seqRes.seqNumTxt.replace(seqRes.seqNum, nextSeq);
                            seqEl.html(nextSeqText);
                        } else {
                            nextSeq++;
                            nextSeqText = seqRes.seqNumTxt.replace(/\d+/g, nextSeq);
                            seqEl.html(nextSeqText);
                        }
                        if (seqRes.nodeText !== seqRes.seqNumTxt) {//需要补充一个span内容
                            seqRes.nodeText = seqRes.nodeText.replace(seqRes.seqNumTxt, "");
                            _this._getSpan().html(seqRes.nodeText).insertAfter(seqEl);
                        }
                    } else {
                        break;
                    }
                } else {
                    count++;
                    if (count > 5) {
                        break;
                    }
                }
                nextPelement = nextPelement.next("._section_div_");
            }
        }
    },
    /**复制 粘贴处理**/
    onPaste: function (e) {       
        var _this = e.data._this;
        _this._makeUndoDataByFocus(true);//记录撤销
        _this._putUndo();
        _this._onChange();
        _this.isPasting = true;
        clearTimeout(_this.isPastingTimer);
        _this.isPastingTimer = setTimeout(function () {
            _this.isPasting = false;
        }, 1000);
        var range = _this.getDomRange();
        var isCollapsed = range.collapsed;
        if (!isCollapsed) {//跨选区不支持
            return false;
        }
        var startOffset = range.startOffset;
        var commonAncestorContainer = range.commonAncestorContainer;
        var nodeValue = commonAncestorContainer.nodeValue;
        var isEmpty = nodeValue === "" || nodeValue === "\u200B";
        var pasteHtml, docSplitHtml;
        var data = e.clipboardData || e.originalEvent.clipboardData;
        var ieData = window.clipboardData;
        var isPureText = false;
        //console.log("paste data >>>>> ");
        // 粘贴过滤了样式的、只有标签的 html
        if (data && data.getData) {
            pasteHtml = data.getData('text/html');
            docSplitHtml = pasteHtml.split('</html>');
            if (docSplitHtml.length === 2) {
                pasteHtml = docSplitHtml[0];
            }
            if (pasteHtml) {
                var bodyStartIndex = pasteHtml.search(/(<body>)|(<body\s+\S+[^>]+>)/gi);
                var bodyStart = pasteHtml.match(/(<body>)|(<body\s+\S+[^>]+>)/gi);
                var bodyEndIndex = pasteHtml.search(/(<\/body>)/gi);
                pasteHtml = pasteHtml.substring(bodyStartIndex + bodyStart[0].length, bodyEndIndex);
                pasteHtml = pasteHtml.replace(/<!--\s*\S+\s*-->/g, "");
                //pasteHtml.replace(/</g, '&lt;').replace(/>/g, '&gt;');
            } else {
                isPureText = true;
                pasteHtml = data.getData('text/plain');
                if (pasteHtml) {
                    pasteHtml = pasteHtml.replace(/[ ]/g, '&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/<!--\s*\S+\s*-->/g, "");
                }
            }
        } else if (ieData && ieData.getData) {
            // IE 直接从剪切板中取出纯文本格式
            pasteHtml = ieData.getData('text');
            isPureText = true;
        }
        var newVals = [], i, len;
        var move2end = true;
        var anchor = _this.getAnchorJqNode();
        var fun = function (content) {
            var add2end = true;
            for (var j = 0, jlen = nodeValue.length; j < jlen; ++j) {
                if (j === startOffset) {
                    newVals.push(content);
                    add2end = false;
                }
                newVals.push(nodeValue[j]);
            }
            if (add2end) {
                newVals.push(content);
            }
            startOffset = startOffset + content.length;
            anchor.html(newVals.join(""));
            var ele = anchor[0].firstChild;
            _this.setCrossRange(ele, ele, startOffset, startOffset);
            move2end = false;
        };
        if (pasteHtml) {
            console.log("paste >>>>>");
            if (isPureText) {//纯文本复制
                pasteHtml = pasteHtml.replace(/\n\r?/g, "");
                if (isEmpty) {
                    anchor.html(pasteHtml);
                    _this.moveToEnd(anchor);
                } else {
                    fun(pasteHtml);
                }
            } else {//复杂内容复制
                //resArray 要确保都是div级别的元素
                var resArray = _this.formatPasteData(pasteHtml);
                var $pel = anchor.parent();
                var isP = false;
                if ($pel[0].tagName === "DIV") {
                    isP = true;
                }
                var _ctx = $pel.text();
                var isEmptyp = _ctx === "" || _ctx === "\u200B";
                var currentNewPel,imgArray = [],aArray = [];   
                var eachImgFn = function(){
                    imgArray.push($(this));
                }; 
                var eachAtagFn = function(){
                    aArray.push($(this));
                };            
                for (i = 0, len = resArray.length; i < len; ++i) {
                    move2end = true;
                    var $c = $(resArray[i]);//$c 一定是div级别的元素
                    $c.css(eConfig.pElementCss);
                    var $tab = $c.children("table");
                    if($tab.length > 0){
                        $tab.siblings().remove();
                    }
                    var imgs = $c.find("img");                    
                    imgs.each(eachImgFn);
                    var atags = $c.find("a");
                    atags.each(eachAtagFn);
                    if (isP) {
                        if (i === 0) {
                            if (isEmptyp) {
                                if ($c[0].tagName === "OL" || $c[0].tagName === "UL") {
                                    $pel.html("");
                                    currentNewPel = $pel.append($c);
                                } else {
                                    if($tab.length > 0){
                                        $pel.children().remove();
                                    }
                                    currentNewPel = $pel.append($c.children().remove());
                                }
                            } else {
                                var newText = $c.text();
                                if (isEmpty) {
                                    anchor.html(newText);
                                } else {
                                    fun(newText);
                                }
                                currentNewPel = $pel;
                            }
                        } else {
                            currentNewPel = $c.insertAfter(currentNewPel);
                            //绑定div事件
                            $c.bind("mouseenter", { "_this": _this }, _this.bindSectionElEvent);  
                        }
                        _this._fixNestSpan(currentNewPel);  //清除嵌套span
                        _this.buildObjectsEventsByTag(currentNewPel);//绑定复制里面的table 链接事件
                    } else {//li 单元格内复制
                        var tmpTxt = [];
                        for (var k = 0, klen = resArray.length; k < klen; ++k) {
                            tmpTxt.push($(resArray[k]).text());
                        }
                        if (isEmpty) {
                            anchor.append(tmpTxt.join(""));
                        } else {
                            fun(tmpTxt.join(""));
                        }
                        break;
                    }
                }
                /**复制中存在的图片***/  
                // var  $img , src ,  reader; 
                // var getLoadFn = function($img){
                //     return function(){
                //         console.log(this.result);
                //     };
                // }; 
                // var $b = _getBody();
                // var $file = $b.children("#_file_reader_input_00");
                // if($file.length === 0){
                //     $file = $('<input type="file" id="_file_reader_input_00" style="display: none">').appendTo($b);
                //     $file.on("change",function(){
                //         var t = this;
                //         console.log("file input change >>>>>>>>");
                //     });
                // }
                // for(i =0 ,len = imgArray.length ; i < len ;++i){
                //     $img = imgArray[i];
                //     src = $img.attr("src");
                //     $file.val(src);
                //     console.log(src);
                //     reader = new FileReader();
                //     reader.readAsDataURL(src);//发起异步请求
                //     reader.onload = getLoadFn($img);
                // }
                for(i =0 ,len = imgArray.length ; i < len ;++i){
                    _this._bindImageEvents(imgArray[i]);
                }
                for(i =0 ,len = aArray.length ; i < len ;++i){
                    _this._bindAEleEvents(aArray[i]);
                }                
                if (isP) {
                    if (currentNewPel.next().length === 0) {
                        var newPel = _this.createPElement().insertAfter(currentNewPel);
                        if(currentNewPel.children("table").length > 0){
                            currentNewPel = newPel;
                        }
                    }
                    if (move2end) {
                        _this.moveToEnd(currentNewPel);
                    }                  
                } else if (move2end) {
                    _this.moveToEnd(anchor);
                }
            }
        }
        return false;
    },
    /***
     * 插入表情、图标，行内图片时候，获取待插入的span
     * ***/
    _getInsertSpan:function(){
        var range = this.range;
        if (range) {
            var endContainer = range.endContainer;
            var endOffset = range.endOffset;
            var nodeValue = endContainer.nodeValue;
            var wrap = $(endContainer.parentNode);
            var copyStyle,targetSapn;
            if (nodeValue !== "" && nodeValue !== "\u200B") {
                var res = $(this._text2spanWrap(nodeValue, 0, endOffset, false));
                res.insertAfter(wrap);
                copyStyle = this._getCopyStyle(wrap);
                wrap.remove();
                var target;
                res.each(function () {
                    var $t = $(this);
                    if ($t.hasClass("_wrap_target_node_")) {
                        target = $t.removeClass("_wrap_target_node_");
                    }
                }).css(copyStyle);
                targetSapn = target;
            } else {
                targetSapn = wrap;
            }
            return targetSapn;
        }        
    },
    /**
     * 将复制的数据格式化为富文本格式的数据
     * **/
    formatPasteData: function (data) {
        var i, len, j, jlen, tmpArr, $c, $span, s;
        var res = [];
        //换行分割
        if(data.indexOf("<") >= 0 && data.indexOf("</") >= 0){ //如果是符合标签元素
            data = data.replace(/\r?\n\r?/g,"");
        }        
        var sections = data.split(/\n\r?|<br>/);
        len = sections.length;
        for (i = 0; i < len; ++i) {
            s = sections[i];           
            s = $.trim(s);
            if (s !== "") {
                tmpArr = this._pasteClear(s);
                for (j = 0, jlen = tmpArr.length; j < jlen; ++j) {
                    $c = $(tmpArr[j]);
                    if ($c[0].tagName === "DIV" && $c.children().length === 0) {
                        $span = this._getSpan().text($c.text());
                        $c.html($span[0].outerHTML);
                    }
                    res.push($c);
                }
            }
        }
        //应该确保res数组元素是段落div级别的  
        len = res.length;
        var setArr = [];
        var tmp, newSection;
        for (i = 0; i < len; ++i) {
            tmp = res[i];
            if (tmp[0].tagName !== "DIV") {
                if (!newSection) {
                    newSection = this.createPElement();
                    setArr.push(newSection);
                }
                if(tmp[0].tagName === "TABLE"){
                    newSection.children().remove();
                }
                newSection.append(tmp);
            } else {
                setArr.push(tmp);
                newSection = undefined;
            }
        }
        return setArr;
    },
    _onPasteReplace:function(html,replaceTable){
        //html = html.replace(/<\/?IMG[^>]*>/gi, "");
        //html = html.replace(/<\/?TABLE[^>]*>/gi, ""); 保留表格复制
        //html = html.replace(/<\/?style[^>]*>/gi, "");
        html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");
        //html = html.replace(/<(\w[^>]*) style="([^"]*)"([^>]*)/gi, "<$1$3") ;
        // Remove Lang attributes
        html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");
        html = html.replace(/<\\?\?xml[^>]*>/gi, "");
        html = html.replace(/<\/?\w+:[^>]*>/gi, "");
        html = html.replace(/ /, " ");
        html = html.replace(/(<b>)|(<b\s+.*?>)/gi, "<span id='" + getUUID() + "' style='font-weight:bold;'>");
        html = html.replace(/(<\/b>)/gi, "</span>");
        html = html.replace(/(<i>)|(<i\s+.*?>)/gi, "<span  id='" + getUUID() + "' style='font-style: italic;'>");
        html = html.replace(/(<\/i>)/gi, "</span>");
        html = html.replace(/(<u>)|(<u\s+.*?>)/gi, "<span  id='" + getUUID() + "' style='text-decoration:underline;'>");
        html = html.replace(/(<\/u>)/gi, "</span>");
        html = html.replace(/(<strike>)|(<strike\s+.*?>)/gi, "<span  id='" + getUUID() + "' style='text-decoration:line-through;'>");
        html = html.replace(/(<\/strike>)/gi, "</span>");

        var re = new RegExp("(<P)([^>]*>.*?)(<\/P>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H1)([^>]*>.*?)(<\/H1>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H2)([^>]*>.*?)(<\/H2>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H3)([^>]*>.*?)(<\/H3>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H4)([^>]*>.*?)(<\/H4>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H5)([^>]*>.*?)(<\/H5>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H6)([^>]*>.*?)(<\/H6>)", "gi");
        html = html.replace(re, "<div   $2</div>");       
        // 剔除span,div ,table tr td 之外的元素
        html = html.replace(/<.*?>/ig, function (tag,arg1,arg2) {                   
            tag = tag.toLowerCase();
            var isTableTag = false;
            if(replaceTable){
                isTableTag = tag.indexOf('</tr>') === 0 || tag.indexOf('<tr ') === 0 || tag.indexOf('<tr>') === 0 ||
                tag.indexOf('</td>') === 0 || tag.indexOf('<td ') === 0 || tag.indexOf('<td>') === 0 ||
                tag.indexOf('</table>') === 0 || tag.indexOf('<table ') === 0 || tag.indexOf('<table>')  === 0 ;
            }            
            if (tag.indexOf('</span>') === 0 || tag.indexOf('<span ') === 0 || tag.indexOf('<span>') === 0 ||
                tag.indexOf('</div>') === 0 || tag.indexOf('<div ') === 0 || tag.indexOf('<div>') === 0 ||
                tag.indexOf('</ol>') === 0 || tag.indexOf('<ol ') === 0 || tag.indexOf('<ol>') === 0 ||
                tag.indexOf('</ul>') === 0 || tag.indexOf('<ul ') === 0 || tag.indexOf('<ul>') === 0 ||
                tag.indexOf('</img>') === 0 || tag.indexOf('<img ') === 0 || tag.indexOf('<img>') === 0 ||
                tag.indexOf('</li>') === 0 || tag.indexOf('<li ') === 0 || tag.indexOf('<li>') === 0 || isTableTag) {
                return tag;
            } else {
                return "";
            }
        });
        // 剔除不配对的非封闭标签
        var emptyStack = [];
        var currentStartTag;       
        html = html.replace(/<.*?>/ig, function (tag,arg1,arg2) { 
            var tagName = tag.match(/<\/?(\w+)/)[1];
            if(tagName === "img"){
                return tag;
            }
            if(tag.indexOf("</") < 0){/**是一个开始标签 **/
                currentStartTag = tagName ;
                emptyStack.unshift(arg1);
            }else{/***当前的封闭标签****/
                if(currentStartTag === tagName){
                    emptyStack.shift();
                }
            } 
            return tag;
        });
        html = html.replace(/<.*?>/ig, function (tag,arg1,arg2) { 
           var isDel = false;
           for(var i = 0 ,len = emptyStack.length ; i < len ; ++i){
                if(emptyStack[i] === arg1){
                    isDel = true;
                }
           }
           if(isDel){
                return "";
           }
           return tag;    
        });
        if(!/^<.*?>/.test(html)){
            var cxt = "";
            if(html === ""){
                cxt = "<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span>";
            }else{
                cxt = "<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span>" + html + "<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span>";
            }
            html = "<div>"+cxt+"</div>";
        }
        return html;
    },
    /**粘贴清理
     * 移除非法属性，非法标签
     * **/
    _pasteClear: function (htmlStr) {
        //console.log(htmlStr);
        var html = this._onPasteReplace(htmlStr,true);       
        var doms = $(html);
        var _this = this;
        var dom, i, len;
        var emptySpan = [];
        var eachChildFn = function () {
            var $el = $(this);
            //解除span里面的嵌套
            _this._removeNestSpan($el);
            _this._removeUnlegalAttr(this,true);
            $el.attr("id", getUUID());
            if ($el.text() === "") {
                emptySpan.push($el);
            }
        };
        var wrapFn = function () {
            if (this.nodeType === 3) {
                var spanHtml = _this._getSpan()[0].outerHTML;
                $(this).wrap(spanHtml);
            }
        };
        for (i = 0, len = doms.length; i < len; ++i) {
            dom = doms[i];
            var $dom = $(dom);
            _this._removeUnlegalAttr(dom);
            if ($dom[0].tagName === "DIV") {
                $dom.addClass("_section_div_");
            }else if($dom[0].tagName === "TABLE"){//clearTable
                _this._pasteTable($dom);
            }
            $dom.children().each(eachChildFn);
            if ($dom.children().length > 0) {
                $dom.contents().each(wrapFn);
            }
        }
        for (i = 0, len = emptySpan.length; i < len; ++i) {
            emptySpan[i].remove();
        }
        //确保div元素的子元素不存在div元素
        var delEles = [];
        doms.children().each(function () {
            var $d = $(this);
            if ($d[0].tagName === "DIV") {
                var $span = _this._getSpan().html($d.text());
                $span.insertAfter($d);
                delEles.push($d);
            }
        });
        for (i = 0, len = delEles.length; i < len; ++i) {
            delEles[i].remove();
        }
        //console.log(">>>>>>>>>>>>>>");
        return doms;
    },
    /**
     * 处理复制中的表格
     * ***/
    _pasteTable:function($tab){
        $tab.attr("id",getUUID()).addClass("k_box_size").css("border-collapse","collapse");
        var $tbody = $tab.children("tbody");
        var trs ;
        if($tbody.length > 0){
            $tbody.attr("id",getUUID());
            trs = $tbody.children();
        }else{
            trs = $tab.children("tr");
        }
        var _this = this;
        trs.each(function(i){
            var tr = $(this);
            tr.attr("id","row_"+i);
            //table 里面的 段落为 p元素
            tr.children().each(function(){
                var td  = $(this);
                var w = td.attr("width");                
                var html = td.html();//处理td内的html，
                var htmlStr = _this._onPasteReplace(html,true);  
                var re = new RegExp("(<div)([^>]*>.*?)(<\/div>)", "gi");
                htmlStr = htmlStr.replace(re, "<p   $2</p>");
                //console.log(htmlStr);
                td.html(htmlStr);
                if(w){
                    w = parseInt( w.replace("pt" , "px"));
                    td.width( w );
                }
                _this._removeUnlegalAttr(this,true);              
            });
        });
    },
    /***
     * 移除嵌套span
     * ***/
    _removeNestSpan: function ($el) {
        if ($el[0].tagName === "SPAN") {
            var text = $el.text();
            $el.children().remove();
            $el.text(text);
        } else {//
            var _this = this;
            var spanHtml = this._getSpan()[0].outerHTML;
            $el.contents().each(function () {
                if (this.nodeType === 3) {
                    $(this).wrap(spanHtml);
                }
            });
            $el.children().each(function () {
                _this._removeNestSpan($(this));
            });
        }
    },
    /**
     * 格式化样式 废弃用不到了！
     * recursion:是否递归处理
     * ***/
    _formatStyle: function ($el,recursion) {
        var style = $el.attr("style");
        $el.attr("id", getUUID());
        if (style) {
            var array = style.split(";");
            var newStyle = {};
            for (var i = 0, len = array.length; i < len; ++i) {
                var tmp = array[i].split(":");
                var name = $.trim(tmp[0]);
                var value = $.trim(tmp[1]);
                if (legalCssStyleNames.indexOf(name) >= 0) {
                    if (name === "font-family") {
                        if (value === 'Microsoft Yahei') {
                            value = '微软雅黑';
                        }
                        if (legalFontFamilys.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "font-size") {
                        if (value.indexOf("pt") > 0) {
                            value = value.replace(/\.[0]+pt/, "");
                            newStyle[name] = fontSizePt2Px[value];
                        } else {
                            newStyle[name] = value;
                        }
                    } else if (name === "font-weight") {
                        if (legalFontWeights.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "font-style") {
                        if (legalFontStyles.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "text-decoration") {
                        if (legalTextDecorations.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "text-align") {
                        if (legalTextAligns.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "background-color" || name === "color") {
                        newStyle[name] = value;
                    } else {
                        newStyle[name] = value;
                    }
                }
            }
            $el.removeAttr("style");
            $el.css(newStyle);
            if(recursion){
                var _this = this;
                $el.children().each(function(){
                    var child = $(this);
                    _this._formatStyle(child,recursion);
                });
            }
        }
    },
    /***
     * 剔除可能引起xss的关键词
     * ** */
    _unhtmlForUrl: function (str, reg) {
        return str ? str.replace(reg || /[<">']/g, function (a) {
            return {
                '<': '&lt;',
                '&': '&amp;',
                '"': '&quot;',
                '>': '&gt;',
                "'": '&#39;',
                "cookie": '',
                "eval": ''
            }[a];
        }) : '';
    },
    /***移除非法属性，并处理style属性值，确保在合法范围内，_formatStyle 可以不需要再调用
     * ,recursion 是否递归
     * ***/
    _removeUnlegalAttr: function (ele,recursion) {
        //console.log("_removeUnlegalAttr >>>>> recursion "+recursion);
        var attrs = ele.attributes || [];              
        ele.setAttribute("id" , getUUID());
        var _this = this;
        var nodeName = ele.nodeName;
        var isP = nodeName === "DIV" || nodeName === "P";
        var k ,v,val,tmpArr,newStyle,tmp,isLegal,j,jlen,pxV,attr,i,len;
        for(i = 0, len = attrs.length ; i < len ; ++i){
            attr = attrs[i];
            if (attr && attr.nodeType === 2) {
                val = attr.value.replace(/pt/g,"px");
                //保留pre里面的data属性,适配适配播放
                if (nodeName === "PRE" && (attr.nodeName === "data" || attr.nodeName === "class")) {
                    val = _this._unhtmlForUrl(val);
                    ele.setAttribute(attr.nodeName, val);
                    return true;
                }
                if (legalAttr.indexOf(attr.nodeName) < 0) {
                    ele.removeAttribute(attr.nodeName);
                } else if (attr.nodeName === "class" && (val.indexOf('_section_div_') < 0) && nodeName !== "PRE") {
                    ele.removeAttribute(attr.nodeName);
                } else {//处理属性值，防止xss
                    if (attr.nodeName !== "style") {
                        val = _this._unhtmlForUrl(val);
                        ele.setAttribute(attr.nodeName, val);
                    }else{//处理style里面不合法的样式
                        tmpArr = val.split(";");
                        newStyle = [];
                        for(j = 0 , jlen = tmpArr.length ; j < jlen ;++j){
                            tmp = tmpArr[j];
                            if(tmp !== ""){
                                tmp = tmp.split(":");
                                if(tmp.length > 1){
                                    k = tmp[0].leftTrim().rightTrim();
                                    v = tmp[1].leftTrim().rightTrim();
                                    isLegal = legalCssStyleNames.indexOf(k) >= 0 || ( isP && pLegalCssStyleNames.indexOf(k) >= 0 );
                                    if (isLegal) {
                                        if (k === "font-family") {
                                            if (v === 'Microsoft Yahei') {
                                                v = '微软雅黑';
                                            }
                                            if (legalFontFamilys.indexOf(v) < 0) {//非法
                                                v = undefined;
                                            }
                                        } else if (v.indexOf("pt") > 0) { //pt转像数
                                            if (v.indexOf("pt") > 0) {
                                                v = v.replace(/\.[0]+pt/, "");
                                                pxV = fontSizePt2Px[v];
                                                if(pxV ){
                                                    v = pxV;
                                                }else{
                                                    v = v + "px";
                                                }
                                            } 
                                        } else if (k === "font-weight") {
                                            if (legalFontWeights.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } else if (k === "font-style") {
                                            if (legalFontStyles.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } else if (k === "text-decoration") {
                                            if (legalTextDecorations.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } else if (k === "text-align") {
                                            if (legalTextAligns.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } 
                                        if(v){
                                            newStyle.push( k + ":" + v);
                                        }                                        
                                    }
                                }                               
                            }
                        }
                        ele.setAttribute(attr.nodeName, newStyle.join(";"));
                    }
                }
            }
        }
        if(recursion){
          for(i =0 ,len = ele.children.length ; i < len ; ++i){
              this._removeUnlegalAttr(ele.children[i] ,recursion );
          }
        }
    },
    /**获取鼠标光标所在的jq对象容器
     * 内部走getDomRange().commonAncestorContainer
     * ***/
    getAnchorJqNode: function () {
        var range = this.getDomRange();
        var anchorNode = range.commonAncestorContainer;
        var node;
        if (anchorNode.nodeType === 3) {
            node = $(anchorNode.parentNode);
        } else {
            node = $(anchorNode);
        }
        return node;
    },
    /***删除键放开后，检查被删除的table对象，处理顺序列表问题
     * ***/
    onDeleteKeyup: function (key) {
        //console.log("key up >>>>>>>>>>>>>>>>>>>>");
        var _this = this;
        _this.removeUselessComponent();
        clearTimeout(this["onDeleteKeyupEvent"]);
        //清理选区，压入undo
        _this.clearUserRange();
        var anchor = _this.getAnchorJqNode();
        //修正空br段落情况
        if (anchor.hasClass("_section_div_")) {
            var childs = anchor.children();
            if (childs.length === 1 && childs.first()[0].tagName === "BR") {
                var id = getUUID();
                anchor.html('<span style="' + eConfig.defaultStyle + '" id="' + id + '">\u200B</span>');
                var node = anchor.children().first();
                _this.moveToEnd(node);
                anchor = _this.getAnchorJqNode();
            }
        }
        if (anchor[0].tagName === "SPAN") {
            var $p = anchor.parent();
            var txt = $p.text();
            if ($p[0].tagName === "LI" && (txt === "\u200B" || txt === "")) {
                var preLi = $p.prev();
                if (preLi.length === 0) {
                    var liParent = preLi.parent();
                    var newSpan = _this._getSpan().insert(liParent);
                    _this.moveToEnd(newSpan);
                    anchor = _this.getAnchorJqNode();
                } else {
                    $p.remove();
                    _this.moveToEnd(preLi);
                    anchor = _this.getAnchorJqNode();
                }
                $p = anchor.parent();
                txt = $p.text();
            }
            var prevEle = $p.prev();
            var nextEle = $p.next();
            if(prevEle.length > 0 && nextEle.length > 0){
                var isEQ1 = _this._getSectionSeqDatas(prevEle).isSeq;
                var isEQ2 = _this._getSectionSeqDatas(nextEle).isSeq;
                if(isEQ1 && isEQ2){
                    _this._fixSeqNum(prevEle, $p, nextEle);
                }   
            }                  
            if (_this.isEmptySection) {
                if (key === 8 && txt === "") {
                    console.log("删除空段落》》》");
                    var prev = $p.prev("._section_div_");
                    if (prev.length > 0) {
                        _this.moveToEnd(prev);
                        $p.remove();
                    }
                } else {
                }
            } else {//如果是图片
                var img = anchor.children("img");
                if (img.length > 0) {
                    img.remove();
                } else {
                    //批量删除空span
                    var delSpan = anchor;
                    var move2end = false;
                    while (delSpan.children().length === 0 && delSpan.prev().length !== 0 && delSpan.text() === "\u200B") {
                        var tmp = delSpan.prev();
                        delSpan.remove();
                        delSpan = tmp;
                        move2end = true;
                    }
                    if (move2end) {
                        _this.moveToEnd(delSpan);
                    }
                    //避免删除后焦点在td中，table下发没有段落内容
                    var nodeAnchor = _this.getAnchorJqNode();
                    var isInTd = false;
                    while (nodeAnchor.length > 0) {
                        var name = nodeAnchor[0].tagName;
                        if (name === "TD") {
                            isInTd = true;
                        }
                        if (name === "LI" || name === "DIV") {
                            break;
                        }
                        nodeAnchor = nodeAnchor.parent();
                    }
                    if (isInTd) {
                        if (nodeAnchor.next().length === 0) {
                            var nextp = _this.createPElement().insertAfter(nodeAnchor);
                            _this.moveToEnd(nextp);
                        }
                    }
                }
            }
        }
        _this.saveUserRange();
        /** 
         * 处理backspace连续按键删除，当前段落被删除场景下的撤销重做问题，在这里修正等待入栈的记录
         * 提取待入栈的undo数据，对比当前鼠标所在段落，检测鼠标所在的段落是否发生变化
         * 如果发生了变化， 则将需要替换的段落改为当前段落，替换内容也要将当前段落加入
         * ***/
        var rec = this["undoRedoRec"];
        if (rec && rec.replaceSectionId.length === 1) {
            anchor = _this.getAnchorJqNode();
            var pele = anchor;
            while (pele.length > 0) {
                if (pele.hasClass("_section_div_")) {
                    break;
                }
                pele = pele.parent();
            }
            var pid = pele.attr("id");
            if (pid !== rec.replaceSectionId[0]) {//段落发生了变化
                rec.replaceSectionId[0] = pid;
                var newHtml = [];
                var cHtml = pele[0].outerHTML;
                var replaceHtml = [];
                var nextSapn = anchor.next();
                while (nextSapn.length > 0) {
                    replaceHtml.push(nextSapn[0].outerHTML);
                    nextSapn = nextSapn.next();
                }
                cHtml = cHtml.replace(replaceHtml.join(""), "");
                newHtml.push(cHtml);
                for (var i = 0, len = rec.html.length; i < len; ++i) {
                    newHtml.push(rec.html[i]);
                }
                rec.html = newHtml;
            }
        }
    },
    /***
     * 如果是序列，则需要修正序列
     * 通过当前行，上一行、下一行对比三行进行顺序列表调整
     * ***/
    _fixSeqNum: function (prevEl, curEl, nextEl) {
        //console.log("修正序列》》》》》》》》》》》");
        var prevSeq = this._getSectionSeqDatas(prevEl);
        var curSeq = this._getSectionSeqDatas(curEl);
        var nextSeq = this._getSectionSeqDatas(nextEl);
        var c1, c2, c3, nextSeqNum, chSeqData;
        var indx1, indx2, indx3;
        if (prevSeq.isSeq && curSeq.isSeq && nextSeq.isSeq) {//三个都是序列
            c1 = this._isSameSeq(prevSeq.seqNumTxt, curSeq.seqNumTxt, prevSeq.seqEl, curSeq.seqEl);
            c2 = this._isSameSeq(curSeq.seqNumTxt, curSeq.seqNumTxt, nextSeq.seqEl, nextSeq.seqEl);
            if (c1 && c2) {
                if (prevSeq.isChSeq) {//中文序列
                    indx1 = getChSeqIndex(prevSeq.seqNum);
                    indx2 = getChSeqIndex(curSeq.seqNum);
                    indx3 = getChSeqIndex(nextSeq.seqNum);
                    c3 = indx1 === (indx2 - 1) && indx2 === (indx3 - 1);
                    if (!c3) {
                        chSeqData = getChNextSeq(prevSeq.seqNum);
                        this._updateSeq(chSeqData, curSeq);
                    }
                } else {
                    c3 = prevSeq.seqNum === (curSeq.seqNum - 1) && curSeq.seqNum === (nextSeq.seqNum - 1);
                    if (!c3) {//需要更新序列                        
                        nextSeqNum = prevSeq.seqNum + 1;
                        this._updateSeq(nextSeqNum, curSeq);
                    }
                }
            }
        } else if (prevSeq.isSeq && nextSeq.isSeq && !curSeq.isSeq) {//当前段落不是序列，但上下段落是序列
            c1 = this._isSameSeq(prevSeq.seqNumTxt, nextSeq.seqNumTxt, prevSeq.seqEl, nextSeq.seqEl);
            if (c1) {
                if (prevSeq.isChSeq) {
                    chSeqData = getChNextSeq(prevSeq.seqNum);
                    this._updateSeq(chSeqData, nextSeq);
                } else {
                    nextSeqNum = prevSeq.seqNum + 1;
                    this._updateSeq(nextSeqNum, nextSeq);
                }
            }
        } else if (!prevSeq.isSeq && !curSeq.isSeq && nextSeq.isSeq) {
            if (nextSeq.isChSeq) {
                this._updateSeq({ index: 0, seq: "一" }, nextSeq);
            } else {
                this._updateSeq(1, nextSeq);
            }
        } else if (!prevSeq.isSeq && curSeq.isSeq && nextSeq.isSeq) {
            c1 = this._isSameSeq(curSeq.seqNumTxt, nextSeq.seqNumTxt, curSeq.seqEl, nextSeq.seqEl);
            if (c1) {
                if (curSeq.isChSeq) {
                    indx2 = getChSeqIndex(curSeq.seqNum);
                    indx3 = getChSeqIndex(nextSeq.seqNum);
                    c3 = indx2 !== indx3 - 1;
                    if (c3) {//需要更新序列
                        chSeqData = getChNextSeq(curSeq.seqNum);
                        this._updateSeq(chSeqData, nextSeq);
                    }
                } else {
                    nextSeqNum = curSeq.seqNum + 1;
                    this._updateSeq(nextSeqNum, nextSeq);
                }
            }
        }
    },
    /***更新序列
     * 中文序列时候 nextSeqNum = {index: seq:}
     * 非中文序列 nextSeqNum = 阿拉伯数字 
     * ***/
    _updateSeq: function (nextSeqNum, nextSeq) {
        var el = nextSeq.seqEl;
        var chSeqIndex;
        if (nextSeq.isChSeq) {//中文序列
            chSeqIndex = nextSeqNum.index;
            el.html(nextSeq.seqNumTxt.replace(nextSeq.seqNum, nextSeqNum.seq));
        } else {
            el.html(nextSeq.seqNumTxt.replace(/\d+/g, nextSeqNum));
        }
        var sesionEl = el.parent().next();
        var sesionElSeq, c, chSeq;
        var count = 0;
        while (sesionEl.length > 0 && (sesionEl[0].tagName === "DIV" || sesionEl[0].tagName === "P")) {
            sesionElSeq = this._getSectionSeqDatas(sesionEl);
            if (sesionElSeq.isSeq) {
                c = this._isSameSeq(nextSeq.seqNumTxt, sesionElSeq.seqNumTxt, nextSeq.seqEl, sesionElSeq.seqEl);
                if (c) {
                    if (sesionElSeq.isChSeq) {
                        chSeqIndex++;
                        chSeq = chSeqArray[chSeqIndex];
                        sesionElSeq.seqEl.html(sesionElSeq.seqNumTxt.replace(sesionElSeq.seqNum, chSeq));
                    } else {
                        nextSeqNum++;
                        sesionElSeq.seqEl.html(sesionElSeq.seqNumTxt.replace(/\d+/g, nextSeqNum));
                    }
                    if (sesionElSeq.nodeText !== sesionElSeq.seqNumTxt) {//需要补充一个span内容
                        sesionElSeq.nodeText = sesionElSeq.nodeText.replace(sesionElSeq.seqNumTxt, "");
                        this._getSpan().html(sesionElSeq.nodeText).insertAfter(sesionElSeq);
                    }
                } else {
                    break;
                }
            } else {
                count++;
                if (count > 5) {
                    break;
                }
            }
            sesionEl = sesionElSeq.seqEl.parent().next();
        }
    },
    /**是否是相同类型的序列**/
    _isSameSeq: function (seq1, seq2, seqEl1, seqEl2) {
        var isTrue;
        seq1 = seq1.replace("\u200B", "");
        seq2 = seq2.replace("\u200B", "");
        if (/\d+/.test(seq1) && /\d+/.test(seq2)) {
            seq1 = seq1.replace(/\d+/g, "");
            seq2 = seq2.replace(/\d+/g, "");
            isTrue = seq1 === seq2;
        } else {//中文序列 [一二三四五六七八九十]+
            seq1 = seq1.replace(/[一二三四五六七八九十]+/, "");
            seq2 = seq2.replace(/[一二三四五六七八九十]+/, "");
            isTrue = seq1 === seq2;
        }
        if (isTrue) { //进一步比较padding-left
            var pading1 = seqEl1.parent().css("padding-left");
            var pading2 = seqEl2.parent().css("padding-left");
            isTrue = pading1 === pading2;
        }
        return isTrue;
    },
    /***
     * 替换完所有不可见字符及空格符
     * srcText :原文本
     * replaceBlank  是否替换空字符
     * ****/
    _replaceAllEmptyChar: function (srcText, replaceBlank) {
        var res = [], tmp;
        if (replaceBlank) {
            srcText = srcText.replace(/\s+/g, "");
        }
        srcText = srcText.replace(/\u200b/g, "");
        return srcText;
    },
    /***
     * 用于自动序列 section = div / p
     * 获取段落的序列信息
     * return {
            isChSeq :是否是中文序列
            isSeq: 是否是序列,
            seqEl: 序列元素,
            emptyEl: 序列元素前方空元素,
            seqNum: 序列数字,
            seqNumTxt: 序列号文本包括空格,
            nodeText: seqEl节点的内容文本
        }
     * ***/
    _getSectionSeqDatas: function (section) {
        var firstTxtEl = section.children().first();
        var txt = firstTxtEl.text();
        var emptyEl = [],
            plainTxt,
            seqNum,
            seqNumTxt,
            isSeq = false,
            isChSeq = false,
            exeRes;
        plainTxt = this._replaceAllEmptyChar(txt, true);
        while (plainTxt === "") {
            emptyEl.push(firstTxtEl);
            firstTxtEl = firstTxtEl.next();
            if (firstTxtEl.length === 0) {
                break;
            }
            txt = firstTxtEl.text();
            plainTxt = this._replaceAllEmptyChar(txt, true);
        }
        //如果plainTxt只是 1,2,3..... 一，二，三需要进一步检查下一个相邻元素是否是【. 、】
        var reg = new RegExp(testSeq);
        if (reg.test(plainTxt)) {
            //console.log("修正序列span 》》》》》》》");
            var nextSpan = firstTxtEl.next();
            var nextTxt = nextSpan.text();
            exeRes = /^[\s\\u200b]*([\.、\)）])[\s\\u200b]*/.exec(nextTxt);
            if (exeRes) {
                var dot = exeRes[0];
                nextSpan.text(nextTxt.replace(dot, ""));
                txt = txt + dot;
                firstTxtEl.text(txt);
            }
        }
        reg = new RegExp(seqexp);
        exeRes = reg.exec(this._replaceAllEmptyChar(txt));
        if (exeRes && exeRes.length > 2) {
            seqNumTxt = exeRes[0];
            if (/^\d+$/.test(exeRes[2])) {
                seqNum = parseInt(exeRes[2]);
            } else {
                seqNum = exeRes[2];
                isChSeq = true;
            }
            isSeq = true;
        }
        return {
            isChSeq: isChSeq,
            isSeq: isSeq,
            seqEl: firstTxtEl,
            emptyEl: emptyEl,
            seqNum: seqNum,
            seqNumTxt: seqNumTxt,
            nodeText: txt
        };
    },        /**
    *通知工具栏 
    **/
    _notifyTools: function (operator, params) {
        if (this.tools && this.tools.notifyTools) {
            this.tools.notifyTools({
                "operator": operator,
                "params": params
            });
        }
    },
    /**
     *重做、撤销通知 
     **/
    _undoRedoNotify: function (name) {
        var prs = {
            undoStackSize: this.undoStack.getLength(),
            redoStackSize: this.redoStack.getLength()
        };
        this._notifyTools(name, prs);
    },
    /**
     * 根据this.range 获取选区涵盖的所有段落
     * forFn：循环回调
     * return :段落数组
     * ***/
    _getRangeSections: function (forFn) {
        var res = [];
        if (!this.range && this.clickActivedObject) {
            var jqObj = this.clickActivedObject.jqObj;
            while (jqObj.length > 0) {
                if (jqObj.hasClass("_section_div_")) {
                    res.push(jqObj);
                    break;
                }
                jqObj = jqObj.parent();
            }
            return res;
        }
        if (!this.range) {
            return res;
        }
        var startContainer = this.range.startContainer; //开始节点
        if (startContainer.nodeType === 1) {
            var tmp = $(startContainer);
            while (tmp.length > 0) {
                if (tmp.hasClass("_section_div_")) {
                    res.push(tmp);
                    if (forFn) {
                        forFn(tmp);
                    }
                    break;
                }
                tmp = tmp.parent();
            }
            return res;
        }
        var endContainer = this.range.endContainer; //结束节点
        var startNode = $(startContainer.parentNode);
        var endNode = $(endContainer.parentNode);
        var startSection = startNode;
        while (startSection.length > 0) {
            if (startSection[0].tagName === "DIV") {
                break;
            }
            startSection = startSection.parent();
        }
        var endSection = endNode;
        while (endSection.length > 0) {
            if (endSection[0].tagName === "DIV") {
                break;
            }
            endSection = endSection.parent();
        }
        if (forFn) {
            forFn(startSection);
        }
        res.push(startSection);
        var nextSection = startSection.next();
        if (endSection[0] !== startSection[0]) {
            while (nextSection.length > 0 && nextSection[0] !== endSection[0]) {
                if (forFn) {
                    forFn(nextSection);
                }
                res.push(nextSection);
                nextSection = nextSection.next();
            }
        }
        if (endSection[0] !== startSection[0]) {
            if (forFn) {
                forFn(endSection);
            }
            res.push(endSection);
        }
        return res;
    },
    /**关闭右键菜单**/
    _closeCxtMenu: function () {
        clearTimeout(this["_closeCxtMenuTimer"]);
        var _this = this;
        this["_closeCxtMenuTimer"] = setTimeout(function () {
            _this._closeCxtMenuImd();
        }, 500);
    },
    _closeCxtMenuImd:function(){
        var m = getSingleton("TableProps",this);
        if (m) {
            m.hide();
        }
        if (this["mousemenu"]) {
            this["mousemenu"].hide();
        }
        this.closeAllWindow();
    },
    /***
     *执行前 ，判断是否需要选区，是否需要undo记录
     ***/
    beforeExecute: function (method, params, button) {
        this._closeCxtMenuImd();
        //源码状态不能执行的操作过滤
        if (method !== "save" && method !== "source" && this["sourceView"]) {
            var display = this["sourceView"].css("display");
            if (display !== "none") {
                return false;
            }
        }
        var go = true;
        if (this.opts.beforeExecute) {
            var res = this.opts.beforeExecute(method, params, button);
            if (typeof res !== 'undefined') {
                go = res;
            }
        }
        /***
         * 该命令是否需要range选区
         * ***/
        if (params.needRange || typeof params.needRange === "undefined") {
            go = typeof this.range !== "undefined";
        }
        /**
         * 没有选区，但是可能clickActivedObject需要执行自定义的处理
         * **/
        if (this.clickActivedObject) {
            go = true;
        }
        if (go) {           
            /***创建一个undo记录***/
            if (params.undo || params.delayUndo) {
                this._onChange();//变化监听
                var isClear = method === "clear";
                if (method === "eraser") { //清除格式支持值清除选择区域
                    var range = this.getDomRange();
                    if (range.collapsed) {
                        isClear = true;
                    } else {
                        isClear = false;
                    }
                }
                this._makeUndoDataByFocus(isClear);
                if (params.undo) {
                    this._putUndo();
                } else {
                    var delay = 500;
                    if (typeof params.delay !== "undefined") {
                        delay = params.delay;
                    }
                    this._putUndoDelayed(delay);
                }
            }
        }
        return go;
    },
    /***
     *执行后 
     ***/
    afterExecute: function (method, params, button) {
        this.cssing = undefined;
        if (this.opts.afterExecute) {
            this.opts.afterExecute(method, params, button);
        }
    },
    /**
     * method:工具栏按钮事件名称
     * params:参数，如果该操作需要撤销，需要传递undo=true参数
     **/
    execute: function (method, params, button) {
        console.log("execute >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + method);
        if (this.beforeExecute(method, params, button)) {
            if (typeof this[method] === "function") {
                //需要选区,选执行一次选取设置
                var needRange = typeof params.needRange === "undefined" || params.needRange;
                if (needRange) {
                    this.setPaintTarget();
                } else if (params.createTargetsByRange) {
                    this.createTargetsByRange();
                }
                var go = true;
                if (this.clickActivedObject) { //如果存在点击对象，进走对象的css修饰
                    var methodName = this.clickActivedObject.className + "Css";
                    if (typeof this[methodName] === "function") {
                        go = this[methodName](method, params, button); //执行特有的修饰
                    }
                }
                if (needRange && this.painTargets.length === 0) {
                    return;
                }
                var ret;
                if (go) {
                    ret = this[method](params, button);
                }                
                this.afterExecute(method, params, button);
                return ret;
            } else {
                alert("找不到handler[" + method + "]");
            }
        }
    },
    /** 恢复段落auto宽度**/
    resetSectionWidth: function () {
        this._onChange();
        var pEl = this.startPElement;
        var pArray = [];
        while (pEl.length > 0) {
            pArray.push(pEl);
            pEl.addClass("k_editor_closed_section");
            pEl.css({ "width": "auto", "margin-left": 0 });
            if (pEl[0] === this.endPElement[0]) {
                break;
            }
            pEl = pEl.next();
        }
        var _this = this;
        setTimeout(function () {
            for (var i = 0, len = pArray.length; i < len; ++i) {
                pArray[i].removeClass("k_editor_closed_section");
            }
        }, 1000);
        if (this.sectionResizeBar) {
            this.sectionResizeBar.remove();
            this.sectionResizeBar = undefined;
        }
        if (this.sectionResizeBar2) {
            this.sectionResizeBar2.remove();
            this.sectionResizeBar2 = undefined;
        }
    },   
    /**设置段落宽度，高亮对应的段落，并显示拖动线
     * onlyHighlight 不需要拖动线出现,只需要高亮当前光标所在的段落
     * **/
    setSectionWidth: function (onlyHighlight) {
        //console.log("setSectionWidth>>>>>>>>> ");
        var _this = this;
        var startPElement = this.startPElement;
        var endPElement = this.endPElement;
        if(!startPElement || startPElement.length === 0){
            $B.alert(eConfig.label.lostfocus,2);
            return;
        }
        var el = startPElement;
        var width = el.outerWidth();
        if (this.resizePelement && this.resizePelement.length > 0) {
            for (var i = 0, len = this.resizePelement.length; i < len; ++i) {
                this.resizePelement[i].removeClass("k_editor_closed_section");
            }
        }
        this.resizePelement = [];
        var fixCount = 0;//预防未知的死循环
        var tmpEl = startPElement;
        while (true) {
            if (parseFloat(el.css("padding-left").replace("px", "")) > parseFloat(tmpEl.css("padding-left").replace("px", ""))) {
                el = tmpEl;
            }
            if (width < tmpEl.outerWidth()) {
                width = tmpEl.outerWidth();
            }
            this.resizePelement.push(tmpEl);
            tmpEl.addClass("k_editor_closed_section");
            if (tmpEl[0] === endPElement[0]) {
                break;
            }
            if (fixCount > 2000) {
                break;
            }
            fixCount++;
            tmpEl = tmpEl.next();
        }
        if (this.sectionResizeBar) {
            this.sectionResizeBar.remove();
        }
        if (this.sectionResizeBar2) {
            this.sectionResizeBar2.remove();
        }
        if(typeof onlyHighlight !== "undefined" && !$.isPlainObject(onlyHighlight)){//只需要高亮 当前激活的段落
            return;
        }
        var fixLeftVal = 0;
        //处理浮动文本场景
        if (this.$input.hasClass("k_editor_float_input")) {
            fixLeftVal = this.$input.parent().position().left;
        }
        var tmpLeft = parseFloat(el.css("margin-left").replace("px", ""));
        var h = this.$inputWrap[0].scrollHeight;//+ this.tools.$wrap.height();
        var sectionResizeBar = $("<div class='k_edit_section_resiez_bar' style='cursor : w-resize;left:" + (width + fixLeftVal + tmpLeft) + "px;height:" + h + "px;position:absolute;top:0;width:5px;z-index:9999999999;border-right:2px solid #FA001D; background:none;opacity:0.65;'></div>");
        this.sectionResizeBar = sectionResizeBar;
        sectionResizeBar.attr("title", eConfig.label.sectionWidth.replace("[x]", width + "像数"));
        var startWidthArray = [];
        var maxLeft = this.$input.width() + fixLeftVal;
        sectionResizeBar.appendTo(this.$inputWrap).draggable({
            axis: 'h',
            cursor: "w-resize",
            onStartDrag: function (args) { //开始拖动
                if (_this.resizeBox) {
                    _this.resizeBox.hide();
                }
                _this._onChange();
                for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                    startWidthArray.push(_this.resizePelement[i].outerWidth());
                }
                console.log("onStartDrag >>>>>>");
            },
            onDrag: function (args) { //拖动中               
                var state = args.state;
                var data = state._data;
                var left = data.left;
                var update = true;
                if (left < 12) {
                    left = 12;
                    update = false;
                }
                if (left > maxLeft) {
                    left = maxLeft;
                    update = false;
                }
                if (update) {
                    var firstW;
                    for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                        var w = startWidthArray[i] + data.leftOffset;
                        if (!firstW) {
                            firstW = w;
                        }
                        _this.resizePelement[i].outerWidth(w);
                    }
                    _this.sectionResizeBar.attr("title", eConfig.label.sectionWidth.replace("[x]", firstW + "像数"));
                }
            },
            onStopDrag: function () {
                startWidthArray = [];
            }
        });
        var inputPaddingLeft = parseFloat(this.$input.css("padding-left").replace("px", ""));       
        var paddleft = tmpLeft + inputPaddingLeft + fixLeftVal;
        var startPaddingArray = [];
        var maxPadding;
        var startElWidthArray = [];
        this.sectionResizeBar2 = $("<div class='k_edit_section_resiez_bar' style='cursor : w-resize;left:" + paddleft + "px;height:" + h + "px;position:absolute;top:0;width:5px;z-index:9999999999;border-left:2px solid #FA001D;background:none;opacity:0.65;'></div>");
        this.sectionResizeBar2.attr("title", eConfig.label.sectionPadding.replace("[x]", tmpLeft + "像数"));
        this.sectionResizeBar2.appendTo(this.$inputWrap).draggable({
            axis: 'h',
            cursor: "w-resize",
            onStartDrag: function (args) { //开始拖动 
                if (_this.resizeBox) {
                    _this.resizeBox.hide();
                }
                _this._onChange();
                var pEl, startPadding, tmpWidth, tmpPadding;
                for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                    pEl = _this.resizePelement[i];
                    tmpWidth = pEl.width();
                    startElWidthArray.push(tmpWidth);
                    startPadding = parseFloat(pEl.css("margin-left").replace("px", ""));
                    startPaddingArray.push(startPadding);
                    tmpPadding = startPadding + tmpWidth - 50 + paddleft;
                    if (!maxPadding) {
                        maxPadding = tmpPadding;
                    } else if (maxPadding > tmpPadding) {
                        maxPadding = tmpPadding;
                    }
                }
            },
            onDrag: function (args) { //拖动中
                var state = args.state;
                var data = state._data;
                var left = data.left;
                var update = true;
                if (left < inputPaddingLeft) {
                    left = inputPaddingLeft;
                    update = false;
                }
                if (left > maxPadding) {
                    left = maxPadding;
                    update = false;
                }
                if (update) {
                    var pEl, startPadding, newPadding, startElWidth, fisrtPadding;
                    for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                        pEl = _this.resizePelement[i];
                        startPadding = startPaddingArray[i];
                        startElWidth = startElWidthArray[i];
                        newPadding = startPadding + data.leftOffset;
                        pEl.css({
                            "margin-left": newPadding
                        });
                        if (!fisrtPadding) {
                            fisrtPadding = newPadding;
                        }
                    }
                    _this.sectionResizeBar2.attr("title", eConfig.label.sectionPadding.replace("[x]", fisrtPadding + "像数"));
                }
            },
            onStopDrag: function () {
                maxPadding = undefined;
                startPaddingArray = [];
                startElWidthArray = [];
            }
        });
    },
    /**循环所有选择的元素，fn循环回调**/
    foreachTargets: function (fn) {
        for (var i = 0, len = this.painTargets.length; i < len; ++i) {
            var t = this.painTargets[i];
            if (!t.hasClass("_exclude_")) {
                var isBreak = fn(t, i);
                if (typeof isBreak !== 'undefined' && !isBreak) {
                    break;
                }
            }
        }
    },
    /**是否是跨段落的选区**/
    isCrossPElement: function () {
        this.setStartAndEndPElementByRange();
        return this.startPElement[0] !== this.endPElement[0];
    },
    /**
     * 根据range找到开始、结束段落
     * this.startPElement 
     * this.endPElement
     * **/
    setStartAndEndPElementByRange: function () {       
        if (this.range) {
            var start = this.range.startContainer;
            if (start.nodeType === 3) {
                start = $(start).parent();
            } else {
                start = $(start);
            }
            while (start.length > 0) {
                if (start.hasClass("_section_div_")) {
                    break;
                }
                start = start.parent();
            }
            var end = this.range.endContainer;
            if (end === this.range.startContainer) {
                end = start;
            } else {
                if (start.nodeType === 3) {
                    end = $(end).parent();
                } else {
                    end = $(end);
                }
                while (end.length > 0) {
                    if (end.hasClass("_section_div_")) {
                        break;
                    }
                    end = end.parent();
                }
            }
            this.startPElement = start;
            this.endPElement = end;
        }
    },
    /**循环选区里的p段落，fn回调**/
    foreachPTargets: function (fn) {
        var i = 0;
        var start = this.startPElement;
        if (!start || start.length === 0) {
            return;
        }
        var go = true;
        if (!start.hasClass("_exclude_")) {
            go = fn(start, i);
        }
        if (typeof go === "undefined") {
            go = true;
        }
        if (go && this.startPElement[0] !== this.endPElement[0]) {
            i = ++i;
            var next = this.startPElement.next();
            while (go && next.length > 0) {
                if (!next.hasClass("_exclude_")) {
                    go = fn(next, i);
                }
                if (typeof go === "undefined") {
                    go = true;
                }
                if (this.endPElement[0] === next[0]) {
                    break;
                }
                next = next.next();
                i = ++i;
            }
        }
    },/**
   * 获取选区里所有颜色的css样式
   * onlyForBrush 是否只用于格式刷的
   * need2p:应用于格式刷时候，是否需要刷段落样式
   * forFontTitle:应用于关联工具栏上的标题/正文
   * **/
    _getRangeCss: function (forBrush,need2p,forFontTitle) {
        var eles, i, len, node, fontSize, fontWeight, fontColor, backgroundColor,
            fontStyle, textDesc, textAlign, verticalAlign, fontFamily;
        var _this = this;
        var css = {
            "font-size": undefined,
            "font-weight": undefined,
            "color": undefined,
            "background-color": undefined,
            "font-style": undefined,
            "text-align": undefined,
            "text-decoration": undefined
        };
        var isEmpty = {};
        var setPeleCssFn = function (node) {
            textAlign = node.css("text-align");
            if (!css["text-align"] && !isEmpty["text-align"]) {
                css["text-align"] = textAlign;
            } else if (css["text-align"] !== textAlign) {
                css["text-align"] = undefined;
                isEmpty["text-align"] = true;
            }
        };
        var setcssFn = function (node) {
            fontSize = node.css("font-size");
            fontWeight = node.css("font-weight");
            fontColor = node.css("color");
            backgroundColor = node.css("background-color");
            fontStyle = node.css("font-style");
            textDesc = node.css("text-decoration");
            verticalAlign = node.css("vertical-align");
            fontFamily = node.css("font-family");

            if (!css["font-family"] && !isEmpty["font-family"]) {
                css["font-family"] = fontFamily;
            } else if (css["font-family"] !== fontFamily) {
                css["font-family"] = undefined;
                isEmpty["font-family"] = true;
            }
            if (!css["vertical-align"] && !isEmpty["vertical-align"]) {
                css["vertical-align"] = verticalAlign;
            } else if (css["vertical-align"] !== verticalAlign) {
                css["vertical-align"] = undefined;
                isEmpty["vertical-align"] = true;
            }
            if (!css["text-decoration"] && !isEmpty["text-decoration"]) {
                css["text-decoration"] = textDesc;
            } else if (css["text-decoration"] !== textDesc) {
                css["text-decoration"] = undefined;
                isEmpty["text-decoration"] = true;
            }
            if (!css["font-style"] && !isEmpty["font-style"]) {
                css["font-style"] = fontStyle;
            } else if (css["font-style"] !== fontStyle) {
                css["font-style"] = undefined;
                isEmpty["font-style"] = true;
            }
            if (!css["background-color"] && !isEmpty["background-color"]) {
                css["background-color"] = backgroundColor;
            } else if (css["background-color"] !== backgroundColor) {
                css["background-color"] = undefined;
                isEmpty["background-color"] = true;
            }
            if (!css["color"] && !isEmpty["color"]) {
                css["color"] = fontColor;
            } else if (css["color"] !== fontColor) {
                css["color"] = undefined;
                isEmpty["color"] = true;
            }
            if (!css["font-weight"] && !isEmpty["font-weight"]) {
                css["font-weight"] = fontWeight;
            } else if (css["font-weight"] !== fontWeight) {
                css["font-weight"] = undefined;
                isEmpty["font-weight"] = true;
            }
            if (!css["font-size"] && !isEmpty["font-size"]) {
                css["font-size"] = fontSize;
            } else if (css["font-size"] !== fontSize) {
                css["font-size"] = undefined;
                isEmpty["font-size"] = true;
            }
        };
        if (this.painTargets.length === 0) {
            this.setPaintTarget();
        }
        eles = this.painTargets;
        if (forBrush) {
            for (i = 0, len = eles.length; i < len; ++i) {
                node = eles[i];
                setcssFn(node);
            }
            var pCss = {};//刷上段落的 margin-left，background-color
            if(need2p){
                this.foreachPTargets(function (p, i) {
                    if (!p.hasClass("_exclude_")) {
                        var cssObj = _this._style2CssObject(p);
                        cssObj["margin-top"] = p.css("margin-top");
                        cssObj["margin-bottom"] = p.css("margin-bottom");
                        cssObj["text-indent"] = p.css("text-indent");
                        cssObj["line-height"] = p.css("line-height");
                        $.extend(pCss,cssObj);
                    }
                });
                css.pCss = pCss;
            }
        } else {
            var child, container, pEl;
            if (this.painTargets.length > 0) {
                for (i = 0, len = this.painTargets.length; i < len; ++i) {
                    child = this.painTargets[i];
                    setcssFn(child);
                }
                pEl = this.startPElement;
                while (pEl.length > 0) {
                    setPeleCssFn(pEl);
                    if (pEl[0] === this.endPElement[0]) {
                        break;
                    }
                    pEl = pEl.next();
                }
            } else {
                var range = this.range;
                if (range) {
                    var ancContainer = range.commonAncestorContainer;
                    if (ancContainer.nodeType === 3) {
                        container = $(ancContainer.parentNode);
                        setcssFn(container);
                    }else{
                        container = $(ancContainer);
                    }
                    pEl = container;
                    while (pEl.length > 0) {
                        if (pEl[0].tagName === "P") {
                            break;
                        }
                        pEl = pEl.parent();
                    }
                    setPeleCssFn(pEl);
                }
            }
        }
        if(forFontTitle && this.startPElement && this.endPElement){
            if(this.startPElement[0] === this.endPElement[0]){
                var h = this.startPElement.height() ;
                var lineH = this.startPElement.css("line-height");
                if(lineH){                   
                    var lh  = parseInt(lineH.replace("px","")) * 1.3;
                    if(h < lh){
                        var fSize,fWeight;
                        this.startPElement.children("span").each(function(){
                            var  $s = $(this);
                            if($s.children("image").length > 0){
                                return true;
                            }
                            var  size = $s.css("font-size");
                            var  weight = $s.css("font-weight");
                            if(!fSize){
                                fSize = size;
                            }else if(fSize !== size){
                                fSize = "14px";
                            }
                            if(!fWeight){
                                fWeight = weight;
                            }else if(fWeight !== weight){
                                fWeight = "400";
                            }
                        });
                        if(fSize && fWeight){
                            css["fontTitle"] = {
                                "line-height": this.startPElement.css("line-height"),
                                "font-size": fSize,
                                "font-weight": fWeight
                            };
                        }
                    }
                }else{
                    console.log("line height >> is undefined >>>");
                }
            }
        }
        return css;
    },
    _hideOthersIconOnTimer:function(){
        var _this = this;
        clearTimeout(this.hideOthersIconTimer);
        this.hideOthersIconTimer = setTimeout(function() {
            _this._hideOthersIcon();
        }, 500);
    },
    /***隐藏其他小图标***/
    _hideOthersIcon:function(){
        var by = _getBody();
        by.children("#k_edit_table_addbtn").hide();
        by.children("#k_edit_table_anchor").hide();   
    },
    /**
     * 删除某一段段落
     * **/
    _removeSection: function (section) {
        var _this = this;
        section.find("table").each(function () {
            _this._deleteTable($(this).attr("id"));
        });        
        section.remove();
        _this._hideOthersIconOnTimer();        
    },
    /**css修饰所选的元素
     * css可以是function，如果是function则需要设置this.cssing
     * **/
    css: function (css) {
        var isFn = typeof css === "function";
        var _this = this;
        //修饰前先计算出当前p段落的行高倍数
        var rates = {};
        var css2p = typeof this.ignorePele === "undefined";
        if (css["font-size"] && css2p) {
            this.foreachPTargets(function (p, i) {
                if (!p.hasClass("_exclude_")) {
                    var r = _this._getLineHeightRate(p);
                    rates[i] = r;
                }
            });
        }
        this.foreachTargets(function ($t, i) {
            if (!$t.hasClass("_exclude_")) {
                if (isFn) {
                    css($t);
                } else {
                    $t.css(css);
                    $t.children("a").css(css); 
                }
            }
        });
        //更新p段落line-height
        if (css["font-size"] && css2p) {
            this.foreachPTargets(function (p, i) {
                if (!p.hasClass("_exclude_")) {
                    var maxFs = _this._getParagraphMaxFontSize(p);
                    var r = rates[i];
                    var line_height = (r * maxFs) + "px";
                    p.css("line-height", line_height);
                    p.find("li").css("line-height", line_height);
                }
            });
        }
        //记录当前正在执行的css修饰，afterExecute清理this.cssing
        if (!isFn) {
            this.cssing = css;
        }
    },
    /**
     * 根据名称获取当前的css值，如果css不一样，返回undefined，否则返回css值
     * //需要对text-decoration 进行处理 剔除solid rgb(102, 102, 102)
     * **/
    getCurrentCssValue: function (cssName) {
        var cssValue;
        this.foreachTargets(function ($t, i) {
            if (!$t.hasClass("_exclude_")) {
                var val = $t.css(cssName);
                if (cssName === "text-decoration") {
                    if (val) {
                        if (val.indexOf("underline") > -1) {
                            val = "underline";
                        }
                        if (val.indexOf("line-through") > -1) {
                            val = "line-through";
                        }
                    }
                }
                if (i === 0) {
                    cssValue = val;
                } else if (cssValue !== val) {
                    cssValue = undefined;
                    return false;
                }
            }
        });
        return cssValue;
    },
    /**
     * 获取ele中第一个子元素的fontSize
     * ***/
    _getFirstCharFontSize: function (ele) {
        var firstCharSize = parseFloat(ele.css("font-size").replace("px", ""));
        var firstEle = ele.children().first();
        var tmp = firstEle.css("font-size");
        if (tmp) {
            tmp = parseFloat(tmp.replace("px", ""));
            if (tmp > firstCharSize) {
                firstCharSize = tmp;
            }
        }
        if (firstEle.children().length > 0 && firstEle[0].previousSibling === null) {
            firstCharSize = this._getFirstCharFontSize(firstEle.children().first());
        }
        return firstCharSize;
    },
    /**
     * 获取ele中第一个子元素的fontSize 
     * 内部调用_getFirstCharFontSize
     * 小于14则返回14
     * ***/
    getFirstCharFontSize: function (ele) {
        var fs = this._getFirstCharFontSize(ele);
        if (fs > 14) {
            return fs;
        }
        return 14;
    },
    /***实现选区实时颜色反馈显示***/
    changeSelectionColor: function (cssName, cssValue) {
        var style = '.k_edit_input_filed *::selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + '}' +
            '.k_edit_input_filed *::-moz-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + '}' +
            '.k_edit_input_filed *::-webkit-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + '}';
        head.children("#_selection_style").remove();
        head.append("<style id='_selection_style'>" + style + "</style>");
    },
    /***
     * 
     * 将dom range提取到{
     *      rangeInfo = {
            startContainerId: startContainerId,
            endContainerId: endContainerId,
            startOffset: this.range.startOffset,
            endOffset: this.range.endOffset
        }
    * ***/
    _getRangeInfo: function () {
        var startContainerId = this.range.startContainer.parentNode.id;
        var endContainerId = this.range.endContainer.parentNode.id;
        var rangeInfo = {
            startContainerId: startContainerId,
            endContainerId: endContainerId,
            startOffset: this.range.startOffset,
            endOffset: this.range.endOffset
        };
        return rangeInfo;
    },
    /**创建\u200B 空文本节点**/
    _createEmptyTextNode: function () {
        var textNode = document.createTextNode("\u200B");
        return textNode;
    },
    /**
     * 在元素前后插入空\u200B字符
     * targetNode：待插入的目标节点
     * isBefore:前插入
     * **/
    _insertEmptyTextNode: function (targetNode, isBefore) {
        var txtNode = this._createEmptyTextNode();
        var parent = targetNode.parentNode;
        if (isBefore) {
            parent.insertBefore(txtNode, targetNode); //将b2插入到div2中的span2前面
        } else {
            if (parent.lastChild === targetNode) {
                parent.appendChild(txtNode);
            } else {
                parent.insertBefore(txtNode, targetNode.nextSibling);
            }
        }
    },
    /** 创建 默认style的 span***/
    _getSpan: function () {
        return $("<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span>");
    },
    /***
     * 设置段落移动
     * ***/
    setSectionMove: function () {
        var _this = this;
        var elArray = [];
        var el = this.startPElement;
        while (el.length > 0) {
            elArray.push(el);
            if (el[0] === this.endPElement[0]) {
                break;
            }
            el = el.next();
        }
        this._setMovingTargets(elArray, false);
    },
    /**
     * 设置移动目标eles = [jq1,jq2] / image 段落元素
     * ***/
    _setMovingTargets: function (eles, isImage, callFn) {        
       // console.log("_setMovingTargets >>>>>>>>");
        if (this.$input.hasClass("k_editor_float_input")) {
            return;
        }
        this.movingTargets = eles;
        this.isMovingImage = isImage;
        var firstEl;
        if (isImage) {
            firstEl = eles;
            var pEle = firstEl.parent();
            while (pEle.length > 0) {
                if (pEle[0].tagName === "DIV") {
                    break;
                }
                pEle = pEle.parent();
            }
            this.moveSrcPele = pEle;
        } else {
            firstEl = eles[0];
            this.moveSrcPele = firstEl;
        }
        //被移动目标所在的段落，及前一个段落
        var prevEl = this.moveSrcPele.prev();
        if (prevEl.length > 0) {
            this.moveSrcBeforePele = prevEl;
        }
        var pos = firstEl.position();
        var scrollTop = this.$inputWrap.scrollTop();
        var top = pos.top + scrollTop;
        var left = pos.left;
        var _this = this;
        _this.onMvAcnClick = callFn;
        if (!this.movingAcn) {
            this.movingAcn = $("<div title='" + eConfig.label.move + "' style='-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;border:1px solid #21F200;position:absolute;z-index:2147483647;left:" + left + "px;top:" + top + "px;padding:0 3px;cursor:move;'><i style='font-weight:bold;font-size:18px;' class='fa fa-move'></i></div>").appendTo(this.$inputWrap);
            this.movingAcn.draggable({
                cursor: 'move',
                onDragReady: function () {
                    _this.movingScroll = false;
                    if (typeof _this.onMvAcnClick === "function") {
                        _this.onMvAcnClick();
                    }
                    return true;
                },
                onStartDrag: function (args) { //开始拖动
                    scrollTop = _this.$inputWrap.scrollTop();
                    _this.movingScroll = true;
                    var state = args.state;
                    var data = state._data;
                    data.left = data.left + 22;
                    data.startLeft = data.startLeft + 22;
                    _this.movingAcn.css("left", data.left);                   
                    var ancStyle = _this._getCopyStyle(_this.movingAcn);
                    var floatPos = { top: parseFloat(ancStyle.top.replace("px", "")), left: parseFloat(ancStyle.left.replace("px", "")) + 26 };
                    _this.movingCopy = $("<div class='k_box_shadow' style='filter: alpha(opacity=80);-moz-opacity: 0.8;-khtml-opacity: 0.8;opacity:0.8;z-index:2147483645;position:absolute;top:" + floatPos.top + ";left:" + floatPos.left + "px'></div>");
                    if (_this.isMovingImage) {//移动图片
                        var w = _this.movingTargets.width();
                        var h = _this.movingTargets.height();
                        _this.movingCopy.css({width:w,height:h});
                        var copyImg = _this.movingTargets.clone();
                        var _f = _this.movingTargets.offset();
                         /**修复图片被浏览器默认拖动机制触发的bug***/
                        _this.imgMask = $("<div style='position:absolute;z-index:2147483600;width:"+(w + 5)+"px;height:"+(h + 5)+"px;top:"+(_f.top - 2)+"px;left:"+(_f.left - 2)+"px;'></div>").appendTo( _getBody() );
                        _this.movingCopy.append("<div style='position:absolute;z-index:2147483646;width:100%;height:100%;'></div>");
                        _this.movingCopy.prepend(copyImg.css({"position":"absolute","margin":0,"z-index":"2147483645","float":"none"})).appendTo(_this.$inputWrap);
                        //console.log("移动图片 >>>>>> 移动图片");                        
                    } else {//移动段落
                        for (var i = 0, len = _this.movingTargets.length; i < len; ++i) {
                            _this.movingCopy.append(_this.movingTargets[i].clone());
                        }
                        _this.movingCopy.appendTo(_this.$inputWrap);
                    }
                    _this.removeSectionResizeBar();  
                    if (_this.resizeBox) {
                        _this.resizeBox.unbind();                     
                    }                  
                },
                onMouseUp: function () {
                    setTimeout(function () {
                        _this.movingTargets = undefined;
                        _this.movingScroll = false;
                        _this.moveSrcBeforePele = undefined;
                        _this.moveSrcPele = undefined;
                        _this.insertAfterTarget = undefined;
                    }, 200);
                },
                onDrag: function (args) {
                    var state = args.state;
                    var data = state._data;
                    _this.movingCopy.css({ top: data.top, left: data.left + 18 });
                },
                onStopDrag: function (args) {                    
                    if(_this.imgMask){
                        _this.imgMask.remove();
                        _this.imgMask = undefined;
                    }                   
                    _this.movingAcn.hide();
                    _this.movingCopy.remove();
                    if (_this.insertAfterTarget) {
                        if (_this.insertLine) {
                            _this.insertLine.remove();
                            _this.insertLine = undefined;
                        }
                        if (_this.isMovingImage) {//如果是图片                                  
                            var newpele = _this.insertPElement(_this.insertAfterTarget);
                            var $img = _this.movingTargets;
                            var imgPt = $img.parent();
                            while (imgPt.length > 0) {
                                if (imgPt[0].tagName === "DIV") {
                                    break;
                                }
                                imgPt = imgPt.parent();
                            }
                            var float = _this._getCopyStyle($img).float;
                            if (float) {//浮动图片
                                newpele.addClass("clearfix");
                                $img.detach().appendTo(newpele);
                                _this._getSpan().insertAfter($img);
                            }
                            if (_this.isEmptySectionFn(imgPt)) {
                                imgPt.detach();
                            } else {
                                imgPt.removeClass("clearfix");
                            }
                        } else {//选择的段落
                            var tmpEl, targetEl = _this.insertAfterTarget;
                            for (var i = 0, len = _this.movingTargets.length; i < len; ++i) {
                                tmpEl = _this.movingTargets[i].detach();
                                targetEl = tmpEl.insertAfter(targetEl);
                            }
                            if(tmpEl.next("._section_div_").length === 0){
                                targetEl = _this.createPElement().insertAfter(tmpEl);
                            }
                            _this.moveToEnd(targetEl);
                        }
                    }
                    _this.insertAfterTarget = undefined;
                    _this.movingTargets = undefined;
                    _this.movingScroll = false;
                    _this.moveSrcBeforePele = undefined;
                    _this.moveSrcPele = undefined;    
                    if(_this.insertLine){
                        _this.insertLine.remove();
                    }             
                }
            });
        } else {
            this.movingAcn.css({ "top": top, "left": left }).show();
        }
    },
    /****
    * 创建当前窗口需要用到的颜色控件，绑定到窗口中
    * ***/
    _createWindowColorPicker: function () {
        if (this[this.windowName] && !this[this.windowName].data("colorPicker")) {
            var pick = new $B.ColorPicker(undefined, {
                update2Target: true,
                showCaret: false
            }).setValue("#A9CADD");
            pick["name"] = "window ColorPicker";
            this[this.windowName].data("colorPicker", pick);
        }
    },
    /**
    * 获取空的p段落用于插入视频、表格、代码
    * ***/
    _getInsertP: function () {
        var targetP;
        this._getRangeSections(function (p) {
            targetP = p;
        });
        var txt = targetP.text().replace(/\u200B/g,"");
        var insertTag;
        if (txt === "" || txt === "\u200B") {
            insertTag = targetP;
        } else {
            var $p = this.createPElement();
            insertTag = $p.insertAfter(targetP);
        }
        return insertTag;
    },
    /**在文本/curentPelement后面插入段落,当存在curentPelement，则插入curentPelement之后
        * return 新建的p
        * **/
    insertPElement: function (curentPelement) {
        var $p = this.createPElement();
        if (curentPelement) {
            $p.insertAfter(curentPelement);
        } else {
            $p.appendTo(this.$input);
        }
        this.moveToEnd($p);
        this.saveUserRange();
        return $p;
    },
    /**获取行高比**/
    _getLineHeightRate: function (pEl) {
        var fs = this._getParagraphMaxFontSize(pEl);
        var lineHeight = parseFloat(pEl.css("line-height").replace("px", ""));
        var rate = lineHeight / fs;
        return rate;
    },
    /**更新行高**/
    _updateParagraphLineHeight: function (pEl, lineHeightRate) {
        var fs = this._getParagraphMaxFontSize(pEl);
        var lineHeight = fs * lineHeightRate;
        pEl.css("line-height", lineHeight + "px");
    },
    /**获取段落内最大字体**/
    _getParagraphMaxFontSize: function (pEl) {
        if(pEl.length === 0){
            return 14;
        }
        var maxFontSize = 0;
        function _loopChild(el) {
            var maxfs = parseFloat(pEl.css("font-size").replace("px", ""));
            if (maxfs > maxFontSize) {
                maxFontSize = maxfs;
            }
            el.children().each(function () {
                var $c = $(this);
                var fs = parseFloat($c.css("font-size").replace("px", ""));
                if (fs > maxFontSize) {
                    maxFontSize = fs;
                }
                $c.children().each(function () {
                    _loopChild($(this));
                });
            });
        }
        _loopChild(pEl);
        return maxFontSize;
    },
    /**将鼠标移动到最后，并调用setCrossRange触发保持更新当前range
     * @param jqElement jq对象
     * **/
    moveToEnd: function (jqElement) {
        //找到最后一个文本节点
        try{
            var lastTextNode = this.getEleLastTextNode(jqElement);
            this.setCrossRange(lastTextNode, lastTextNode, lastTextNode.length, lastTextNode.length);
        }catch(ex){
            console.log("moveToEnd is exception");
        }        
    },
    /**
     * 移动到目标的开始位置
     * ***/
    moveToStart: function (jqElement) {
        var lastTextNode = this.getEleLastTextNode(jqElement);
        this.setCrossRange(lastTextNode, lastTextNode, 0, 0);
    },
    /**
     * 添加节点到targets中
     * isLoopChild是否包含子节点
     * **/
    _putNodeToTargets: function (jqNode, isLoopChild) {
        var _this = this;
        if (jqNode.length > 0 && !jqNode.data(selectDataKey)) {
            var tagName = jqNode[0].tagName;
            if (elementToTargets[tagName]) {//检测是否允许设置到目标中
                this.painTargets.push(jqNode);
                jqNode.data(selectDataKey, true);
            }
            if (isLoopChild) {
                //递归子元素
                jqNode.children().each(function () {
                    _this._putNodeToTargets($(this), true);
                });
            }
        }
    },
    /**
     * 清空paintargets 元素标志
     * **/
    _clearDataKeys: function () {
        this.foreachTargets(function (t) {
            t.removeData(selectDataKey);
        });
    },
    /**将text用span包装**/
    _loopSpanWrapText: function (wrap) {
        var childNodes = wrap.childNodes;
        for (var i = 0, len = childNodes.length; i < len; ++i) {
            var node = childNodes[i];
            if (node.nodeType === 3) {//找到文本节点,并且需要包装,这里需要过滤 <span>\u200b<img>\u200b</span>
                var pNode = node.parentNode;
                if($(pNode).children("img").length > 0){//img标签 不做包装处理
                    continue;
                }
                var childrenLength = node.parentNode.children.length;
                if (childrenLength > 0 && pNode.childNodes.length > childrenLength) {
                    var id = getUUID();
                    var html = "<span style='" + eConfig.defaultStyle + "' id='" + id + "'>" + node.nodeValue + "</span>";
                    var nextSibling = node.nextSibling;
                    if (nextSibling) {
                        $(html).insertBefore($(nextSibling));
                    } else {
                        $(html).insertAfter($(node.previousSibling));
                    }
                    node.parentNode.removeChild(node);
                    this.isNeedToReplace = true;
                }
            } else { //标签节点，继续递归
                this._loopSpanWrapText(node);
            }
        }
    },
    /***清理p标签下无用的span标签***/
    _getUselessSpan: function (ele) {
        var _this = this;
        for (var i = 0, len = ele.children.length; i < len; ++i) {
            var node = ele.children[i];
            //有子元素，并且没有任何属性则说明这是个无用的span
            if (node.children.length > 0) {
                if (node.attributes.length === 0) {
                    this.uselessSpan.push(node);
                }
            }
            _this._getUselessSpan(node);
        }
    },
    /***
     * 采用DocumentFragment避免解析过程中触发页面渲染
     * 利用span包装所有的text文本
     * pElement p段落标签
     * ***/
    _spanWrap2Text: function (pElement) {
        //跳过代码块
        var childrens = pElement.children();
        if (childrens.length < 2 && childrens.children("pre").length > 0) {//代码块
            return;
        }
        if(childrens.first()[0].tagName === "PRE"){//视频
            return;
        }
        //console.log("_spanWrap2Text >>>> ");
        var newFrag = document.createDocumentFragment();
        newFrag.appendChild(document.createElement("div"));
        var wrap = newFrag.firstChild;
        wrap.innerHTML = pElement[0].outerHTML;
        var ele = wrap.firstChild;
        this.isNeedToReplace = false;
        this._loopSpanWrapText(ele);
        this.uselessSpan = [];
        this._getUselessSpan(ele);
        for (var i = 0, len = this.uselessSpan.length; i < len; ++i) {
            var delSpan = $(this.uselessSpan[i]);
            delSpan.children().remove().insertAfter($(delSpan));
            delSpan.remove();
            this.isNeedToReplace = true;
        }
        if (this.isNeedToReplace) {
            var style = this._getCopyStyle(pElement);
            $(wrap).children().children().each(function () {
                $(this).css(style);
            });
            pElement.html(wrap.children[0].innerHTML);
        }
    },
    /**
     * 查询node节点所在的段落元素
     * **/
    _findNodePElement: function (node) {
        var parent = node;
        while (true) {
            if (parent.length === 0 || (parent[0].tagName === sectionTag && parent.hasClass("_section_div_")))  {
                break;
            }
            parent = parent.parent();
        }
        return parent;
    },
    /**
     * child是否被parentEl包含
     * 同一个元素 为true
     * **/
    _contains: function (parentEl, child) {
        var isContains = false;
        if (parentEl[0] === child[0]) {
            return true;
        }
        var pEl = child.parent();
        while (pEl[0].tagName !== sectionTag) {
            if (pEl[0] === parentEl[0]) {
                isContains = true;
                break;
            }
            pEl = pEl.parent();
        }
        return isContains;
    },
    /**
     * 将文本分割为span标签包装/n
     * range里面的startOffset，endOffset/n
     * splitCheck:分割检查，传值则说明不处理全选的情况,全选时候直接返回“”
     * **/
    _text2spanWrap: function (text, startOffset, endOffset, splitCheck) {
        if (text === '\u200B' || text === "") {
            return "";
        }
        if (splitCheck) {
            var offSetCount = endOffset - startOffset;
            if (offSetCount === text.length) {
                return "";
            }
        }
        //分割为三个组
        var array1 = [],
            array2 = [],
            array3 = [],
            txt = '',
            startIndex = startOffset,
            endIndex = endOffset;
        var span1 = $("<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'/>");
        var span2 = $("<span class='_wrap_target_node_' style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span>");
        var span3 = $("<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'/>");
        for (var i = 0, len = text.length; i < len; ++i) {
            txt = text[i];
            if (txt === '\u200B') {
                continue;
            }
            if (i < startIndex) {
                array1.push(txt);
            } else if (i >= startIndex && i < endIndex) {
                array2.push(txt);
            } else {
                array3.push(txt);
            }
        }
        var html1 = array1.join("").replace(/<span\s+\S+\s*><\/span>/g, "");
        var html2 = array2.join("");
        var html3 = array3.join("").replace(/<span\s+\S+\s*><\/span>/g, "");
        var tmp = [];
        if (html1 !== "") {
            span1.text(html1);
            tmp.push(span1[0].outerHTML);
        }
        if (html2 !== "") {
            span2.text(html2);
        }
        tmp.push(span2[0].outerHTML);
        if (html3 !== "") {
            span3.text(html3);
            tmp.push(span3[0].outerHTML);
        }
        return tmp.join("");
    },
    /**将ele元素的style属性创建为对象副本返回,用于合并到子元素样式
     * 对td / p 进行过滤不需要设置到子元素的样式
     * **/
    _getCopyStyle: function (ele) {
        var cssObj = this._style2CssObject(ele);
        if (ele[0].tagName === "TD") {
            cssObj = {
                "background-color": cssObj["background-color"],
                "color": cssObj["color"],
                "font-weight": cssObj["font-weight"],
                "font-style": cssObj["font-style"],
                "text-decoration": cssObj["text-decoration"],
                "font-family": cssObj["font-family"],
                "font-size": cssObj["font-size"],
                "letter-spacing": cssObj["letter-spacing"],
            };
        } else if (ele[0].tagName === "DIV") {
            delete cssObj["text-indent"];
            delete cssObj["line-height"];
            delete cssObj["width"];
            delete cssObj["padding-left"];
            delete cssObj["padding-right"];
            delete cssObj["margin-top"];
            delete cssObj["margin-bottom"];
        }
        return cssObj;
    },
    /***
     * 提取style 为 json对象返回,用于全量复用
     * ***/
    _style2CssObject: function (ele, notExt) {
        var style = ele.attr("style");
        var styles = {};
        if (style) {
            var tmpArr = style.split(";");
            for (var i = 0, len = tmpArr.length; i < len; ++i) {
                if (tmpArr[i] !== "") {
                    var s = tmpArr[i].split(":");
                    var key = $.trim(s[0]);
                    var val = $.trim(s[1]);
                    if (notExt || !extCopyCfg[key]) {
                        styles[key] = val;
                    }
                }
            }
        }
        return styles;
    },
    /***清空painTargets 
     * 但不影响range
     * ***/
    _removePainTargets: function () {
        this._clearDataKeys();
        this.painTargets = [];
    },
    /***
     * 清空选区range记录
     * ***/
    _clearRangeRecord: function () {
        this._removePainTargets();
        this.isFindedStartNode = false;
        this.isFindedEndNode = false;
        this.startPElement = undefined;
        this.endPElement = undefined;
        head.children("#_selection_style").remove();
    },
    /**如果存在选区则提取修饰目标，否则不提取修饰目标
     * 先_removePainTargets后再setPaintTarget
     * **/
    createTargetsByRange: function () {
        if (this.range && !this.range.collapsed) {
            this._removePainTargets();
            this.setPaintTarget();
        }
    },
    /**
     * 获取开始/结束目标节点
     * **/
    _getStartEndtNode: function (container, isStart, isCross) {
        var tag, i, len, tempNode;
        if (container.nodeType === 3) {
            var wrap = $(container.parentNode);
            var nodeValue = container.nodeValue;
            var isSelectAll = false;
            var endIndex;
            var startIndex;
            if (isCross) { //跨标签选择
                if (isStart) { //解析的是开始节点
                    isSelectAll = this.startOffset === 0 && container.parentNode.nodeName !== sectionTag && container.parentNode.children.length === 0;
                    startIndex = this.startOffset;
                    endIndex = nodeValue.length; //- 1;
                } else { //解析的是结束节点
                    isSelectAll = nodeValue.length === this.endOffset && container.parentNode.nodeName !== sectionTag && container.parentNode.children.length === 0;
                    startIndex = 0;
                    endIndex = this.endOffset;
                }
            } else {
                startIndex = this.startOffset;
                endIndex = this.endOffset;
                //判断是否是全选
                isSelectAll = startIndex === 0 && nodeValue.length === this.endOffset && container.parentNode.nodeName !== sectionTag && container.parentNode.children.length === 0;
            }
            //var i ,len;
            if (isSelectAll) { //标签被全选
                tag = wrap;
            } else {
                var style;
                var _html = this._text2spanWrap(nodeValue, startIndex, endIndex);
                var $html = $(_html);
                if (wrap.children().length === 0) { //纯文本节点
                    style = this._getCopyStyle(wrap);
                    $html.css(style);
                    if (wrap[0].tagName === "SPAN") {
                        // for(i = 0 ,len = spansArray.length ; i < len ; ++i){
                        //     spansArray[i].css(style);
                        // }
                        $html.insertAfter(wrap);
                        // var removeNodeId = wrap.attr("id");
                        wrap.remove();
                    } else {
                        wrap.html($html);
                    }
                    for (i = 0, len = $html.length; i < len; ++i) {
                        tempNode = $($html[i]);
                        if (tempNode.hasClass("_wrap_target_node_")) {
                            tag = tempNode;
                            break;
                        }
                    }
                } else {
                    var nextSibling = container.nextSibling;
                    var retTags, $sibling;
                    if (nextSibling) {
                        $sibling = $(nextSibling);
                        style = this._getCopyStyle($sibling.parent());
                        retTags = $html.css(style).insertBefore($sibling);
                    } else {
                        $sibling = $(container.previousSibling);
                        style = this._getCopyStyle($sibling.parent());
                        retTags = $html.css(style).insertAfter($sibling);
                    }
                    container.parentNode.removeChild(container);
                    tag = retTags.filter("._wrap_target_node_");
                }
            }
        } else { //如果容器的标签节点                
            if (container.childNodes.length === 1) {
                tag = $(container);
            } else {
                tag = $(container);
            }
        }
        return tag.removeClass("_wrap_target_node_");
    },
    /**将p段落的所有子span元素放到修饰数组中**/
    _putPelChild2Targets: function (pEl) {
        var _this = this;
        pEl.find("span").each(function () {
            _this._putNodeToTargets($(this), false);
        });
    },
    /***将父元素的nextAll、prevAll里面的span放到修饰数组中
     * 应对 开始、结束标签在li、td里面的情况
     * ***/
    _putParentEl2Targets: function (parentEl, isStart) {
        if (parentEl.length === 0 || parentEl[0].tagName === "DIV") {
            return;
        }
        var _this = this;
        var isGo = true;
        if (isStart) {
            parentEl.nextAll().each(function () {
                if (_this._endNodeParent[0] !== this) {
                    _this._putNodeToTargets($(this), true);
                } else {
                    isGo = false;
                    return false;
                }
            });
        } else {
            parentEl.prevAll().each(function () {
                if (_this._startNodeParent[0] !== this) {
                    _this._putNodeToTargets($(this), true);
                } else {
                    isGo = false;
                    return false;
                }
            });
        }
        if (isGo) {
            this._putParentEl2Targets(parentEl.parent(), isStart);
        }
    },
    /**根据光标/选区设置修饰目标,不包含段落标签
     * 设置成功：return true / false
     * **/
    setPaintTarget: function () {
        var _this = this;
        var range = this.range;
        if (!range) {
            return false;
        }
        //避免拖动过程中重新设置 painTargets
        if (this.painTargets.length > 0) {
            var domRange = this.getDomRange();
            if (!domRange.collapsed) { //查看当前保存的选区和dom的一致
                if (domRange.startContainer === range.startContainer && domRange.endContainer === range.endContainer) {
                    return true;
                }
            } else {
                this.clearUserRange();
            }
        }
        if (!range.collapsed) { //如果选择了内容
            var startTag = null,
                endTag = null;
            this.startOffset = range.startOffset;
            this.endOffset = range.endOffset;
            this.endContainer = range.endContainer;
            this.startContainer = range.startContainer;
            var isCross = this.startContainer !== this.endContainer;
            if (isCross) { //跨标签选择
                //开始标签
                startTag = this._getStartEndtNode(this.startContainer, true, isCross);
                //结束标签
                endTag = this._getStartEndtNode(this.endContainer, false, isCross);
                this.startPElement = this._findNodePElement(startTag);
                this.endPElement = this._findNodePElement(endTag);
            } else { //选区同一个标签，开始节点，结束节点是一致的
                startTag = this._getStartEndtNode(this.startContainer, true, isCross);
                endTag = startTag;
                this.startPElement = this._findNodePElement(startTag);
                this.endPElement = this.startPElement;
            }
            //打上标签ID      
            startTag.attr("class", "_k_edit_start_node_");
            if (isCross) {
                endTag.attr("class", "_k_edit_end_node_");
            }
            /***
             * 处理p标签里面混合标签、文字的情况
             * ***/
            var startPEle = this.startPElement;
            while (startPEle.length > 0) {
                var childs = startPEle.children();
                if (childs.length === 1 && childs.first()[0].tagName !== "TABLE") {
                    this._spanWrap2Text(startPEle);
                }
                if (startPEle[0] === this.endPElement[0]) {
                    break;
                }
                startPEle = startPEle.next();
            }
            startTag = this.startPElement.find("._k_edit_start_node_").removeClass("_k_edit_start_node_");
            if (isCross) {
                endTag = this.endPElement.find("._k_edit_end_node_").removeClass("_k_edit_end_node_");
            } else {
                endTag = startTag;
            }
            if (startTag.length === 0 && endTag.length > 0) {
                startTag = endTag;
            }
            if (endTag.length === 0 && startTag.length > 0) {
                endTag = startTag;
            }
            if (startTag.length === 0 && endTag.length === 0) {
                return false;
            }
            //做一次span嵌套清理
            var tmpPel = this.startPElement;
            while (tmpPel.length > 0) {
                this._fixNestSpan(tmpPel);
                tmpPel = tmpPel.next();
                if (tmpPel[0] === this.endPElement[0]) {
                    break;
                }
            }
            //恢复选区 	并将修饰目标放到Targets中			
            this.createCrossRange(startTag, endTag);
            this._putNodeToTargets(startTag, true);
            //startTag \ endTag肯定是span,span的parent可能是div、li、td
            //用于 _putParentEl2Targets 
            this._startNodeParent = startTag.parent();
            var tagName;
            while (this._startNodeParent.length > 0) {
                tagName = this._startNodeParent[0].tagName;
                if (tagName === "DIV" || tagName === "LI" || tagName === "TD" || tagName === "TR" || tagName === "P") {
                    break;
                }
                this._startNodeParent = this._startNodeParent.parent();
            }
            this._endNodeParent = endTag.parent();
            while (this._endNodeParent.length > 0) {
                tagName = this._endNodeParent[0].tagName;
                if (tagName === "DIV" || tagName === "LI" || tagName === "TD" || tagName === "TR" || tagName === "P") {
                    break;
                }
                this._endNodeParent = this._endNodeParent.parent();
            }
            if (isCross) {
                var nextEle = startTag.next();
                while (nextEle.length > 0 && nextEle[0] !== endTag[0]) {
                    this._putNodeToTargets(nextEle, false);
                    nextEle = nextEle.next();
                }
                if (this._startNodeParent[0] !== this._endNodeParent[0]) {
                    this._putParentEl2Targets(startTag.parent(), true);
                }
            }
            //跨段落
            if (this.startPElement[0] !== this.endPElement[0]) {
                tmpPel = this.startPElement.next();
                while (tmpPel.length > 0) {
                    if (tmpPel[0] === this.endPElement[0]) {
                        break;
                    }
                    this._putPelChild2Targets(tmpPel);
                    tmpPel = tmpPel.next();
                }
            }
            //设置结束标签
            if (this._startNodeParent[0] !== this._endNodeParent[0]) {
                this._putParentEl2Targets(endTag.parent(), false);
                var preEles = endTag.prevAll();
                preEles.each(function () {
                    _this._putNodeToTargets($(this), false);
                });
            }
            this._putNodeToTargets(endTag, true);
        } else { //如果没有选择内容，将提取光标所在的元素，及开始段落，结束段落
            var ancContainer = range.commonAncestorContainer;
            if (ancContainer.nodeType === 3) {
                ancContainer = $(ancContainer.parentNode);
            } else {
                ancContainer = $(ancContainer);
            }
            this.painTargets.push(ancContainer);
            this.startPElement = this._findNodePElement(ancContainer);
            this.endPElement = this.startPElement;
        }
        this._startNodeParent = undefined;
        this._endNodeParent = undefined;
        clearTimeout(this.clearTargetdataflagTimer);
        this.clearTargetdataflagTimer = setTimeout(function () {
            _this._clearDataKeys();
        }, 500);
        return true;
    },
    /**修正段落内的span嵌套span***/
    _fixNestSpan: function (pElement) {
        //console.log("_fixNestSpan  >>>>>>> _fixNestSpan");
        var _this = this;
        var clearFn = function () {
            var tmpEl = $(this);
            var tmpChild = tmpEl.children("span");
            if (tmpChild.length > 0) {
                var pStyle = _this._getCopyStyle(tmpEl);
                tmpChild.each(function () {
                    var $c = $(this);
                    var cStyle = _this._getCopyStyle($c);
                    $c.css($.extend(pStyle, cStyle));
                });
                tmpChild.detach().insertAfter(tmpEl);
                tmpEl.remove();
            }
        };
        pElement.children("span").each(clearFn);
    },
    /***
     * 段落鼠标enter事件
     * **/
    bindSectionElEvent: function (e) {
        var _this = e.data._this;
        if (_this.movingScroll) {
            if (_this.moveSrcPele[0] !== this && (!_this.moveSrcBeforePele || _this.moveSrcBeforePele[0] !== this)) {               
                var el = $(this);
                var pos = el.position();
                var scrollTop = _this.$inputWrap.scrollTop();
                var mvData = _this.movingAcn.data('_mvdata');
                var acnPos, cpPos, diff, go2Upate = false;
                if (pos.top < 0) {
                    go2Upate = true;
                    var prev = el.prev();
                    if (prev.length > 0) {
                        pos = prev.position();
                    }
                    diff = pos.top;
                } else {
                    var height = _this.$inputWrap.height();
                    var pHeight = el.height();
                    var maxTop = pHeight + pos.top;
                    diff = maxTop - height;
                    if (diff > 0) {
                        go2Upate = true;
                        var nextEl = el.next();
                        if (nextEl.length > 0) {
                            diff = diff + 22;
                        }
                    }
                }
                if (go2Upate) {
                    scrollTop = scrollTop + diff;
                    _this.$inputWrap.scrollTop(scrollTop);
                    //调整scrolltop后 修改位置                        
                    mvData.top = mvData.top + diff;
                    mvData.startTop = mvData.startTop + diff;
                    acnPos = _this.movingAcn.position();
                    cpPos = _this.movingCopy.position();
                    _this.movingAcn.css("top", acnPos.top + diff);
                    _this.movingCopy.css("top", cpPos.top + diff);
                }
                if (!_this.insertLine) {
                    _this.insertLine = $("<div class='clearfix' style='height:12px;position:relative;'><i style='z-index:2;font-weight:bold;font-size:10px;color:#21F200;position:absolute;top:0;left:0;z-index:1;' class='fa fa-right-open-2'></i><div class='k_box_size' style='border-left:4px solid #fff;top:5px;height:2px;background:#21F200;float:left;width:100%;position:absolute;'></div></div>");
                } else {
                    _this.insertLine.remove();
                }
                _this.insertLine.insertAfter(el).show();
                _this.insertAfterTarget = el;
            } else {
                _this.insertAfterTarget = undefined;
                if(_this.moveSrcPele[0] === this){
                    if(_this.insertLine){
                        _this.insertLine.hide();
                    }
                   //console.log("移动到原来的位置》》》》");
                }
            }
        }
    },
    /**
     * 设置数据
     * **/
    setContent: function (datas) {
        if (typeof datas === "string") {
            datas = $(datas);
        }
        var _this = this;
        //处理浮动文本、图片           
        var floatTxt = $("<div></div>");
        var text = $("<div></div>");
        var videoPreArray = [];
        var i, len;
        for (i = 0, len = datas.length; i < len; ++i) {
            var tmp = datas[i];
            var $tmp = $(tmp);
            var pre = $tmp.children("pre");
            if (pre.length === 0) {
                $tmp.children("span").children("pre");
            }
            var html, $i;
            if (pre.length > 0) { // pre标签保持原样
                if (pre.hasClass('k_video_pre')) {
                    html = tmp.outerHTML.replace(/[\n\r]/g, "").replace(/>[\s]+</g, "><");
                    $i = $(html);//替换回车换行
                    pre = $i.children("pre");
                    videoPreArray.push(pre);
                } else {
                    var pId = pre.parent().attr("id");
                    pre.remove();
                    html = tmp.outerHTML.replace(/[\n\r]/g, "").replace(/>[\s]+</g, "><");
                    $i = $(html);//替换回车换行
                    $i.find("#" + pId).append(pre);
                }
            } else {
                //代码块场景 
                var allSpan = $tmp.children("span");
                var isCodePre = false; 
                if( allSpan.length < 4 && allSpan.children("pre").length > 0){
                    isCodePre = true;
                }
                html = tmp.outerHTML;
                if(!isCodePre){
                    html = html.replace(/[\n\r]/g, "").replace(/>[\s]+</g, "><");
                }               
                $i = $(html);//替换回车换行
            }
            if ($i.hasClass("_section_div_")) {
                text.append($i);
            } else if ($i.hasClass("k_edit_float_panel")) {
                floatTxt.append($i);
            }
        }
        var ps = text.children().remove();
        ps.appendTo(this.$input);
        this.buildObjectsEventsByTag(ps);
        var allPeles = this.$input.children();
        allPeles.bind("mouseenter", { "_this": this }, this.bindSectionElEvent);       
        var lastP = allPeles.last();
        var children = lastP.children();
        if (children.length === 1) {
            var name = children.first()[0].tagName;
            if (name === "IMG" || name === "TABLE") {
                lastP = this.insertPElement();
            }
        }        
        var floatPanels = floatTxt.children().remove();
        this.$inputWrap.append(floatPanels);
        floatPanels.each(function () {
            var $t = $(this);
            var inputWrap = _this._bindFloatPanelEvents($t);
            if (inputWrap) {
                var pres = inputWrap.children("div");
                _this.buildObjectsEventsByTag(pres);
                pres.children("pre").each(function () {
                    var $pre = $(this);
                    if ($pre.hasClass("k_video_pre")) {
                        videoPreArray.push($pre);
                    }
                });
            }
        });       
        setTimeout(function () {
            var firstPle = _this.$fixInput.children().first();
            if(firstPle.hasClass("_exclude_")){
                firstPle = firstPle.next();
                if(firstPle.length === 0 || firstPle[0].tagName === "IMG" || firstPle[0].tagName === "TABLE"){
                    firstPle = _this.insertPElement();
                }
            }           
            _this.moveToEnd(firstPle);
            var videoPre, videoOpt;
            for (i = 0, len = videoPreArray.length; i < len; ++i) {
                videoPre = videoPreArray[i];
                videoOpt = JSON.parse(videoPre.attr("data").replace(/&quot;/g, "\""));
                _this._createVideoPlayer(videoPre, videoOpt);
            }
            videoPreArray = undefined;
        }, 1);
    },
    /***
     * replace(/&lt;/g, "<").replace(/&gt;/g, ">")
     * decodeURIComponent
     * 后调用setContent
     * ***/
    setHtmlString: function (data) {
        var str = data.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
        str = decodeURIComponent(str);
        this.setContent(str);
    },
    /**
     * 内容恢复后对table、a 、prev video标签进行对象创建，事件绑定
     * **/
    buildObjectsEventsByTag: function (wrap) {       
        if(wrap.length === 0){
            return;
        }
        var _this = this;
        //恢复表格
        var rebuildTableFn = function () {
            var tableTag = $(this);
            tableTag.css({
                "border-collapse": "collapse",
                "width": "auto",
                "height": "auto",
                "cursor": "default"
            });
            //初始化table
            tableTag.find("td.k_edit_selected_td_shadow").removeClass("k_edit_selected_td_shadow");
            var table = new Table(_this).initByJq(tableTag);
            _this.tables.push(table);
        };
        //恢复a标签
        var buildAFn = function () {
            _this._bindAEleEvents($(this));
        };
        //恢复image事件
        var buildImgFn = function () {
            _this._bindImageEvents($(this));
        };
        //代码块事件
        var buildCodeFn = function () {
            var $pre = $(this);
            if ($pre.hasClass("k_video_pre")) {
                _this._bindVideoEvents($pre);
            } else {
                _this._bindPreEvents($pre);
            }
        };
        //恢复重建事件
        wrap.each(function () {
            var div = $(this);
            if (div.hasClass("k_split_line")) {//恢复分割线事件
                _this._bindSplitLineEvent(div);
            } else {
                var tabs = div.children("table").each(rebuildTableFn);
                var as = div.find("a").each(buildAFn);
                var imgs = div.find("img").each(buildImgFn);
                if (tabs.length === 0 && as.length === 0 && imgs.length === 0) {
                    div.children("span").children("pre").each(buildCodeFn);
                    var pres = div.children("pre");
                    if (pres.length === 0) {
                        pres = div.children("pre");
                    }
                    pres.each(buildCodeFn);
                }
            }
        });
        //console.log("buildObjectsEventsByTag >>>>>>>> buildObjectsEventsByTag");
    },
    /**
     * dom转存html时候，处理视频容器
     * ***/
    _fixVideoHtml: function($el){
        if($el.length === 0){
            return ;
        }        
        var videoWrap = $el.children(".video-js");
        if (videoWrap.length > 0) {
            var video = videoWrap.children("video").remove();
            var videoId = video.attr("id").replace("_html5_api", "");
            video.attr("id", videoId).insertAfter(videoWrap);
            //补充上videojs的自动 data-setup
            var prop = $el.attr("data").replace(/&quot;/g, "\"");
            video.attr("data-setup", prop).addClass("video-js vjs-default-skin vjs-big-play-centered");
            videoWrap.remove();
        }
    },
    /***循环移除不需要的属性***/
    _loopElClearUnlegalAttr: function (el) { 
        var isVideoEl = !(el.nodeName !== "PRE" || (el.nodeName === "PRE" && ! $(el).hasClass("k_video_pre")));
        if(isVideoEl){
            this._fixVideoHtml($(el));
        }
        //this._removeUnlegalAttr(el); 
        //if (el.nodeName !== "PRE" || (el.nodeName === "PRE" && ! $(el).hasClass("k_video_pre"))) {            
            // for(var i = 0 ,len = el.children.length ; i < len ; ++i ){
            //     this._loopElClearUnlegalAttr(el.children[i]);
            // }
        // } else {//处理视频容器
        //    this._fixVideoHtml($(el));
        // }
    },
    /**
     * 获取数据
     * urlEncode:是否url 编码
     * **/
    getContent: function (urlEncode) {
        //var startDate = new Date();
        var res,
            floatHtmls ;
        if(this.currentHTML){
            res = this.currentHTML;           
        }else{
            res = this.$fixInput.children().clone();
        }           
        if(this.currentFloatHTML){
            floatHtmls = this.currentFloatHTML;
        }else{
            floatHtmls = this.$inputWrap.children(".k_edit_float_panel").clone();
        }
        this._clearCurrentHtml();
        var html = [], phtml, tag, $tag,i = 0, len,id;       
        for (i = 0, len = res.length; i < len; ++i) {
            tag = res[i];
            $tag = $(tag);
            // id = $tag.attr("id");
            this._loopElClearUnlegalAttr(tag);
            if ($tag.hasClass("_section_div_close_title") && $tag.attr("closed_status")) {
                var closeCount = parseInt($tag.attr("closed_count"));
                var j = i, tmpTag;
                while (closeCount > 0) {
                    tmpTag = $(res[j + 1]);
                    j++;
                    closeCount--;
                    tmpTag.css("display", "none");
                }
            }
            phtml = tag.outerHTML.replace(/cursor:\s*((?!;).)+;/g, "");
            if (urlEncode) {
                phtml = encodeURIComponent(phtml);
            }
            html.push(phtml);
        }      
        var _this = this;
        //浮动文本 、图片
        for (i = 0, len = floatHtmls.length; i < len; ++i) {
            $tag = $(floatHtmls[i]);
            $tag.children(".k_editor_float_input").removeAttr("contenteditable");
            _this._loopElClearUnlegalAttr($tag[0]);
            phtml = $tag[0].outerHTML.replace(/cursor:\s*((?!;).)+;/g, "");
            if (urlEncode) {
                phtml = encodeURIComponent(phtml);
            }
            html.push(phtml);
        }
        // var endDate = new Date();
        // console.log("time " + (endDate - startDate));
        return html.join("");
    },    
    /**
     *清空用户选择的选区 
     **/
    clearUserRange: function (clearDom) {
        if (clearDom) {
            var selection = this.getDomSelection();
            try {
                selection.removeAllRanges();
            } catch (e) { }
        }
        this.range = undefined;
        this._clearRangeRecord();
    },
    /***
     *重建用户选区 
     *rangeInfo = {startContainerId,endContainerId, startOffset,endOffset}
     *当存在rangeInfo参数时候以rangeInfo创建选区
     *否则以this.range作为恢复记录（用于焦点变化的重建）
     ***/
    rebuildUserRange: function (rangeInfo) {
        try {
            if (rangeInfo) {
                var startContainerId = rangeInfo.startContainerId,
                    endContainerId = rangeInfo.endContainerId;
                var startContainer = this.$input.find("#" + startContainerId)[0];
                var endContainer = this.$input.find("#" + endContainerId)[0];
                startContainer = this.getEleFirstTextNode(startContainer);
                endContainer = this.getEleLastTextNode(endContainer);
                this.setCrossRange(startContainer, endContainer, rangeInfo.startOffset, rangeInfo.endOffset);
            } else {
                if (this.range) {
                    var selection = this.getDomSelection();
                    try {
                        selection.removeAllRanges();
                    } catch (e) { }
                    selection.addRange(this.range);
                }
            }
        } catch (ex) {
            console.log("rebuildUserRange error !");
        }
    },
    /**
     *保存当前dom中用户选择的选区 
     **/
    saveUserRange: function () {
        // console.log(" saveUserRange saveUserRange saveUserRange");
        var r = this.getDomRange();
        //修正startContainer、 endContainer不是textNode的情况
        if (!r) {
            return;
        }
        this.range = r;
    },
    /***获取container的文本节点，如果没有文本节点则补充上文本节点
     * 用于解析提取range中的开始、结束文本节点
     * ***/
    _getContainerTextNode: function (container, isEnd) {
        var child,$p;
        if (isEnd) {
            child = container.lastChild;
            if(child.nodeName === "IMG"){
                $p = $(child.parentElement);
                $p = this._getSpan().insertAfter($p);
                child =  $p[0].firstChild;
            }
        } else {
            child = container.firstChild;
            if(child.nodeName === "IMG"){
                $p = $(child.parentElement);
                $p = this._getSpan().insertBefore($p);
                child =  $p[0].firstChild;
            }
        }
        var parentNode;
        if (child) { //存在子节点
            if (child.nodeType === 1) { //子节点是非文本元素
                if (child.tagName === "BR") {
                    parentNode = child.parentNode;
                    parentNode.removeChild(child);
                    if (parentNode.tagName === "SPAN") {
                        child = $(parentNode).html("\u200B")[0].firstChild;
                    } else {
                        child = this._getSpan().appendTo($(parentNode))[0].firstChild;
                    }
                } else if (child.tagName === "TABLE") {//跳到第一个单元格
                    var firstTd = $(child).children("tbody").children().first().children().first();
                    child = this.getEleLastTextNode(firstTd);
                } else if (child.tagName !== "SPAN") { //如选择的是img/td/a标签
                    console.log("选区边界元素非span元素》》》》》》》》》》》》》》》》》》》》》！");
                } else {
                    child = child.firstChild;
                    if (child && child.nodeType !== 3) {
                        parentNode.removeChild(child);
                        child = $(parentNode).html("\u200B")[0].firstChild;
                    }
                }
            } else { //子节点是文本元素
                return child;
            }
        } else { //不存在子节点
            if (container.tagName === "DIV") {
                child = this._getSpan().appendTo($(container))[0].firstChild;
            } else {
                child = $(container).html("\u200B")[0].firstChild;
            }
        }
        return child;
    },
    /***提取dom的range，而且不做任何处理* **/
    _getDomRangeOnly: function () {
        var range;
        var seletionObj = this.getDomSelection();
        if (seletionObj.getRangeAt && seletionObj.rangeCount > 0) {
            range = seletionObj.getRangeAt(0);
        } else { // 老版本浏览器
            if (seletionObj.anchorNode) {
                range = document.createRange();
                range.setStart(seletionObj.anchorNode, seletionObj.anchorOffset);
                range.setEnd(seletionObj.focusNode, seletionObj.focusOffset);
            }
        }
        return range;
    },
    /***
     * 创建div 段落
     * **/
    createPElement: function () {
        var id = getUUID();
        var id2 = getUUID();
        var $p = $("<" + sectionTag + " id='" + id + "' class='_section_div_'><span style='" + eConfig.defaultStyle + "' id='" + id2 + "'>\u200B</span></" + sectionTag + ">");
        $p.css(eConfig.pElementCss);
        $p.bind("mouseenter", { "_this": this }, this.bindSectionElEvent);       
        return $p;
    },
    /***
     * 获取dom range，对startContainer、endContainer非文本节点进行修正
     * 返回的range，确保startContainer、endContainer是文本节点
     * isFixContainer:是否需要修正开始、结束节点为文本节点，默认true
     * 2019-06-26 修复开始、结束节点为img的场景bug
     * ***/
    getDomRange: function (isFixContainer) {
        var range = this._getDomRangeOnly();
        if (range) {
            try {
                //fix startContainer endContainer 保证这两个节点必须为文本节点
                var start = range.startContainer;
                var end = range.endContainer;
                var need2fix = false;
                var isFix = typeof isFixContainer === "undefined" ? true : isFixContainer;
                var firstChild = start,
                    lastChild = end,
                    startOffset, endOffset;
                if (start.nodeType === 1) {
                    if (isFix) {
                        need2fix = true;
                        if(start.nodeName === "IMG"){                            
                            firstChild = start.nextSibling;
                        }else{
                            firstChild = this._getContainerTextNode(start);
                        }
                        startOffset = 0;
                    }
                } else {
                    startOffset = range.startOffset;
                }
                if (end.nodeType === 1) {
                    if (isFix) {
                        if (start === end) {
                            lastChild = firstChild;
                        } else {
                            if(end.nodeName === "IMG"){                                
                                lastChild = end.previousSibling;
                            }else{
                                lastChild = this._getContainerTextNode(end, true);
                            }                            
                        }
                        need2fix = true;
                        endOffset = lastChild.nodeValue.length;
                    }
                } else {
                    endOffset = range.endOffset;
                }
                if (need2fix) { //需要修正
                    //console.log("需要修正 非文本节点");
                    if (firstChild === lastChild && startOffset === 0 && endOffset === 1) {
                        startOffset = 1;
                    }
                    range = this.setCrossRange(firstChild, lastChild, startOffset, endOffset);
                }
                //ie fix startContainer bug
                if (start.nodeType === 3 && !range.collapsed) {
                    if (range.startOffset === start.length) {
                        range = this.createCrossRange(end, end);
                    }
                }
                return range;
            } catch (ex) {
                return undefined;
            }
        }
    },
    /***
     *获取dom中选区 
     ***/
    getDomSelection: function () {
        var selection;
        if (window.getSelection) {
            selection = window.getSelection();
        } else if (document.selection) {
            selection = document.selection.createRange();
        }
        return selection;
    },
    /**
     * 获取ele元素下第一个text文本节点
     * **/
    getEleFirstTextNode: function (ele) {
        
        if (ele.nodeType === 3) {
            return ele;
        }else{
            if (ele.tagName === "IMG") {
                ele = this._getSpan().insertBefore($(ele).parent());
            }
        }
        var childNodes;
        if (ele.css) {
            childNodes = ele[0].childNodes;
        } else {
            childNodes = ele.childNodes;
        }
        var firstEle  = childNodes[0];
        if (firstEle.nodeType === 3) {
            return firstEle;
        }
        if (firstEle.tagName === "IMG") {
            firstEle = this._getSpan().insertBefore($(firstEle).parent());
        }
        return this.getEleFirstTextNode(firstEle);
    },
    /**
     * 获取ele元素下最后一个text文本节点
     * **/
    getEleLastTextNode: function (ele) {
        if (ele.nodeType === 3) {
            return ele;
        }else{
            if (ele.tagName === "IMG") {
                ele = this._getSpan().insertAfter($(ele).parent());
            }
        }
        var childNodes;
        if (ele.css) {
            childNodes = ele[0].childNodes;
        } else {
            childNodes = ele.childNodes;
        }
        var lastEle = childNodes[childNodes.length - 1];
        if (!lastEle) {
            console.log("异常！！！！");
            return;
        }
        if (lastEle.nodeType === 3) {
            return lastEle;
        }
        if (lastEle.tagName === "IMG") {
            lastEle = this._getSpan().insertAfter($(lastEle).parent());
        }
        return this.getEleLastTextNode(lastEle);
    },
    /**创建新的选区
     * 确保新的range里开始节点、结束节点为text-node类型
     * start ：此处为jq对象 / 文本节点;
     * end ：此处为jq对象 / 文本节点
     * **/
    createCrossRange: function (start, end) {
        var firstTextNode = this.getEleFirstTextNode(start);
        var lastTextNode = this.getEleLastTextNode(end);
        return this.setCrossRange(firstTextNode, lastTextNode, 0, lastTextNode.length);
    },
    /***
     * firstChild：开始节点，必须为文本节点;
     * lastChild：结束节点，必须为文本节点;
     * startOffset：开始位置;
     * endOffset：结束位置
     * ***/
    setCrossRange: function (firstChild, lastChild, startOffset, endOffset) {
        try {
            var range = document.createRange();
            range.setStart(firstChild, startOffset);
            range.setEnd(lastChild, endOffset);
            var sel = window.getSelection();
            try {
                sel.removeAllRanges();
            } catch (ex) { }
            sel.addRange(range);
            this.range = range;
            this.setStartAndEndPElementByRange();
            return this.range;
        } catch (ex) {
            console.log("error");
        }
    },
    /**
     * section是否是空段落
     * **/
    isEmptySectionFn: function (section) {
        var txt = section.text().replace(/[\s*\u200B]*/g, "");
        var isEmpty = txt === "";
        if (isEmpty) {
            var tables = section.find("table").length;
            var imgs = section.find("img").length;
            isEmpty = tables === 0 && imgs === 0;
        }
        return isEmpty;
    },
    /**
     *获取选区开始节点/结束节点所在的段落jq对象 
     *isStart : 获取开始节点所在段落，否则获取结束节点所在段落
     * **/
    getRangeSection: function (isStart) {
        var section;
        if (this.range) {
            var container = this.range.endContainer;
            if (isStart) {
                container = this.range.startContainer;
            }
            if (container.nodeType === 3) {
                container = container.parentNode;
            }
            while (container) {
                if (container.nodeName === "DIV") {
                    section = container;
                    break;
                }
                container = container.parentNode;
            }
            if (section) {
                var tmp = $(section);
                if (tmp.hasClass("_section_div_")) {
                    section = tmp;
                } else {
                    section = undefined;
                }
            }
        }
        return section;
    },
    destroy: function () {
        var i,len;
        for(i = 0 ,len = this.tables.length ; i < len ; ++i){
            if(this.tables[i].remove){
                this.tables[i].remove();
            }
        }
        this.FLOW_CACHE = undefined;
        clearInterval(this._cache_clearner);
        $(document).off("mousedown."+this.id);  
        if (this["mousemenu"]) {
            this["mousemenu"].remove();
        }
        if (this["tipWindow"]) {
            this["tipWindow"].remove();
        }
        if (window["TableProps"] && window["TableProps"].destroy) {
            window["TableProps"].destroy(this);
        }
        if (this.windowArray) {
            for (i = 0, len = this.windowArray.length; i < len; ++i) {
                var w = this.windowArray[i];
                if (w.data("colorPicker")) {
                    w.data("colorPicker").destroy(this);
                }
                if (w.remove) {
                    w.remove();
                }
            }
        }
        if (this.super) {
            this.super.destroy.call(this);
        }
        //处理视频videojs，避免html加载方式下，videojs内部记录的数据不销毁
        if (window["videojs"]) {
            var players = window["videojs"].getPlayers();
            if (players) {
                for (var p in players) {
                    if (players.hasOwnProperty(p)) {
                        delete players[p];
                    }
                }
            }
        }
    }
};
